我有数千个没有特定扩展名的文件。我需要做的是在文件名中搜索字符串并用其他字符串替换,然后进一步搜索第二个字符串并用任何其他字符串替换等等。例如:我有多个字符串需要用其他多个字符串替换。它可能像:
- 文件名中的“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 脚本来做会更好吗?
答案1
如果您可以使用 Bash,那么以下脚本应该可以执行您想要的操作:
#!/bin/bash
(( $# != 2 )) && exit 1
for f in *; do
newf="${f//$1/$2}"
if [[ $f != $newf ]]; then
mv "$f" "$newf"
fi
done
它会尝试用新字符串替换文件名,如果结果文件名与原始文件名不匹配,则它会将文件重命名为结果文件名。
用法,如果保存为replacestr
并给定要执行的模式:
$ ./replacestr abc def
它将尝试重命名所有内容。您可以使用[[ ! -f $f ]]
它来跳过非文件。~/.bashrc
如果您经常需要它,您还可以将其包装在函数中并从您的源中获取它。
答案2
答案3
您使用的任何脚本都可能存在潜在危险,但这对我来说在有限的范围内有效(我只接触了大约 15 个文件并快速执行了 abc,123 \n def,456 - 等的 csv。
解决了这个问题后,我会快速备份,在几个设备上进行测试,然后推出它。
假设:
-excel 导出为 CSV,oldname,newname
每行都有格式
-您在 bash shell 中。-
所有内容都在一个目录中-它们都是文件(您可以通过更改为
将脚本更改为目录-type f
-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
答案4
在 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 标志包含子目录)。然后,它将文件名通过管道传输到 findstr 命令中,该命令会将其与针字符串进行比较。如果找到匹配项,则打印该行,但被 抑制> nul
。如果未找到匹配项,则将错误级别设置为 1,之后&&
将阻止执行命令的其余部分。
然后将变量%%i
复制到 中%match%
,因为迭代器形式不支持子字符串替换。然后,使用改变的目标字符串 ,通过移动命令重命名文件名!match:%needle%=%replace%!
。
请注意,拼写错误或错误可能会弄乱您的文件名。请谨慎使用。