查找和替换文件名中的字符串


1

我有成千上万的文件,没有特定的扩展名。我需要做的是搜索文件名中的sting并替换为其他字符串并进一步搜索第二个字符串并替换为任何其他字符串,依此类推。即:我有多个字符串可以替换为其他多个字符串。它可能像:

  • 文件名中的“abc”替换为“def”***字符串“abc”可能在许多文件中
  • 文件名中的“jkl”替换为“srt”***字符串“jkl”可能位于许多文件中
  • 文件名中的“pqr”替换为“xyz”***字符串“pqr”可能位于许多文件中

我目前正在使用excel宏来获取excel中的文件名,然后在一列中保留原始名称并替换在其他列中复制的内容中所需的名称。然后我为它创建一个批处理文件。喜欢:

rename Path\OriginalName1 NewName1
rename Path\OriginalName2 NewName2

上述过程的问题在于文件很多需要花费很多时间。当我使用excel 2003时,行数也有限制。我需要一个批量的脚本,如:

replacestr  abc with def
replacestr  pqr with xyz

在一个目录中。在unix脚本中做得更好吗?


新的或旧文件名中的任何逗号或任何内容都重要吗?
nerdwaller

文件名中没有逗号。
shekhar

perl -pi -e 's;original;replacement;g' list of files to munge
vonbrand 2013年

Answers:


3

如果您可以使用Bash,那么以下脚本应该执行您想要的操作:

#!/bin/bash

(( $# != 2 )) && exit 1

for f in *; do
  newf="${f//$1/$2}"
  if [[ $f != $newf ]]; then
    mv "$f" "$newf"
  fi
done

它尝试用新字符串替换filename,如果生成的文件名与原始文件名不匹配,则将文件重命名为结果文件名。

用法,如果保存为replacestr和要执行的给定模式:

$ ./replacestr abc def

它会尝试重命名所有。您可以使用[[ ! -f $f ]]跳过非文件。~/.bashrc如果您经常需要,也可以将其包装在功能中并从中获取。


它工作正常。重命名所有我只是创建另一个脚本与多个$ ./replacestr实例... ...
shekhar

1

你使用的任何脚本都可能有危险,但这对我有限的规模(我只触及了大约15个文件并快速执行了abc,123 \ n def,456等)。

有了这个,我会做一个快速备份,测试几个,然后推出它。

假设
- 将excel导出为CSV,oldname,newname每行
都有格式- 你在bash shell中。
- 所有在一个目录中
- 它们都是文件(您可以通过更改-type f为将脚本更改为dirs-type d

#!/bin/bash
inputfile=${1}
while read line
do
    IFS=',' read -a names <<< "${line}"
    for file in `find . -maxdepth 1 -type f -name "*${names[0]}*"`; do
        rename "s/${names[0]}/${names[1]}/" *
    done
done < ${inputfile}

这将从当前目录(find .)工作,只能在1级(-maxdepth 1)上工作,项目很容易更改。希望至少让你走上正轨。

重要的是,这将保留文件名的其余部分,并仅用输出替换输入字符串。因此123abc123.null 输入的文件abc,999会导致123999123.null

只需使其可执行chmod +x nameofmyscript.sh并执行它./nameofmyscript.sh input/file/location.csv


每次执行代码时,它都会显示如下错误:第9行C:用户.... ** <没有反斜杠的路径结构> **:否此类文件或目录。我正在使用GitBash
shekhar

这假设你是一个bash shell,你显然是在Windows ...(假设2)所以如果你想尝试它,你需要在unix bash shell中。
nerdwaller

0

这里是一个不错的HOWTO。有许多收件人,甚至是脚本。我希望你能找到你想要的东西。

实际上,您应该学习正则表达式以更好地理解该主题。


谢谢。正如我所说,没有特定的扩展名和要替换的字符串可能在文件名中的任何位置不在开头或结尾。Howto链接对我没用。
shekhar

0

在Windows批处理文件中:

@echo off
setlocal enabledelayedexpansion
set needle=%~1
set replace=%~2
pushd %3
for %%i in (*.*) do (
    echo %%i|findstr "%needle%"> nul && (set match=%%i&move /-Y "%%i" "!match:%needle%=%replace%!")
)
popd

示例语法: batchrename.bat "abc" "def" ".\bigfolder"

它的工作原理是更改当前目录(如果指定了一个),使用它来遍历它for(使用/ R-flag包含子目录)。然后它将文件名传递给findstr命令,该命令将它与针字符串进行比较。如果找到匹配项,则会打印该行,但会被抑制> nul。如果未找到匹配项,则将errorlevel设置为1,之后将&&阻止执行命令的其余部分。

%%i然后将变量复制到%match%,因为迭代器形式不支持子串替换。然后,使用更改的目标字符串通过move-command重命名文件名!match:%needle%=%replace%!

请注意,拼写错误或错误可能会弄乱您的文件名。谨慎使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.