我试图重命名文件夹中包含的文件&子文件夹。我在每个文件夹下包含各种文件的许多子文件夹,所以我的目标是在顶级文件夹中运行一个脚本,希望扫描整个子文件夹数组,并将旧文件名重命名为新文件名。一个单独的文本文件。
例如:
Abc075.tif ---------- Xyz.tif
def958.pdf ---------- pqr.pdf
我的这个bash脚本适用于文件夹级别,如果我将其复制到每个文件夹(和子文件夹),然后从那里运行。
#!/bin/bash
while read -r old new
do
arr=( ${old} )
if (( ${#arr[@]} == 1 ))
then
mv "${arr[0]}" "$new"
else
echo "Error: Multiple files found for $old: ${arr[@]}"
fi
done < replace.txt
抱歉,我的知识有限,但我已尝试将其修改为;
#!/bin/bash
find -type f -iname '*.*' -print0 | while read -r old new
do
arr=( ${old} )
if (( ${#arr[@]} == 1 ))
then
mv "${arr[0]}" "$new"
else
echo "Error: Multiple files found for $old: ${arr[@]}"
fi
done < replace.txt
这会执行但不会奏效。我还使用这个find命令尝试了第一个脚本;
find /path -type f -name "*.*" -exec /path_of_script.sh {} +
非常感谢提前。
答案 0 :(得分:3)
要使用批处理mv
命令,您需要创建一个制表符分隔文件,该文件将明确添加您的replace.txt未命中的目录结构,如下所示:
full/path/old.stuff<TAB>full/path/new.stuff
为了达到这个目的,你必须:
mv
命令。 因此我们需要使用大表格和find
,basename
和join
等工具进行一些步骤(后者还需要进行一些排序)强>
1)转到必须进行更改的最上面的目录,然后从:
开始find . > all_paths.ls
然后我们得到类似于你在replace.txt中的基本名称:
for path in `cat all_paths.ls` ; do basename $path ; done > all_names.ls
我们还需要dirnames:
for path in `cat all_paths.ls` ; do dirname $path ; done > all_dirs.ls
2)这两个将创建一个有用的表(组合名称以匹配您的replace.txt文件,同时仍然跟踪dirs):
paste all_names.ls all_dirs.ls > all_name-dir.tsv
3)由于join
的魔力,我们现在使用你的replace.txt文件:
sort replace.txt > replace.sorted.txt
sort all_name-dir.tsv > all_name-dir.sorted.tsv
# join will work fine because "old basenames" are in the first column of both tables
join -t "<TAB>" all_name-dir.sorted.tsv replace.sorted.txt > todo_name-dir-newname.tsv
<TAB>
代表真正的制表符(您可以使用CTRL + V然后选择TAB键在shell中输入)
结果应该有三列,内容如下:
old.stuff<TAB>full/path/<TAB>new.stuff
4)为了能够通过move命令使用所有这些,我们只需稍微重新塑造这个并将路径粘合在一起(放一些&#34; /&#34;返回)
# get the columns back
cut -f2 < todo_name-dir-newname.tsv > todo_dirs.ls
cut -f1 < todo_name-dir-newname.tsv > todo_oldnames.ls
cut -f3 < todo_name-dir-newname.tsv > todo_newnames.ls
# glue 2 and 1 together for reconstructed old paths
paste todo_dirs.ls todo_oldnames.ls | tr "\t" "/" > todo_oldpaths.ls
# same for the new ones
paste todo_dirs.ls todo_newnames.ls | tr "\t" "/" > todo_newpaths.ls
# and we get the table we wanted
paste todo_oldpaths.ls todo_newpaths.ls > replace_table.tsv
5)现在终于你可以继续前进:
for line in `cat replace_table.tsv`
do oldpath=`echo $line | cut -f1`
newpath=`echo $line | cut -f2`
mv $oldpath $newpath
done