这里新(和编码)。我正在编写一个简单的bash脚本,可以帮助我将字符更改为当前目录的所有文件中的另一个字符。这是代码:
#!/bin/bash
#this script changes characters in all files of the current directory
NUM=$(ls -1 | wc -l | awk '{print $1}')
echo "There are $NUM files in this folder."
echo "Changing $1 to $2 in all their names..."
echo "Done! Here's what happened:"
for i in $(seq 1 $NUM)
do
OLDNAME=$(ls -1 | head -$i | tail -1)
NEWNAME=$(ls -1 | head -$i | tail -1 | sed -e "s/${1}/${2}/g")
mv -v "$OLDNAME" "$NEWNAME"
done
因此,如果我写./ccin.sh " " "_"
,它应该将当前目录中所有文件名称中的所有空格更改为下划线。除了它没有,我认为这是ls
的错。 for
循环正在跳过某些文件,因为ls
会根据每次mv
有效修改其中一个文件对文件进行排序来更改顺序。所以我需要以不依赖于“last modified”属性的方式隔离文件的名称。我想到了文件大小,但是如果有两个大小相同的文件,这将无法工作 - 例如,我在一个充满空文件的目录上尝试此代码。
是否可以使用ls
对文件进行排序,使其保持与mv
修改其名称相同的顺序?
答案 0 :(得分:1)
你可以试着用这个代替你的for循环:
find . -type f | while read file
do
OLDNAME="$file"
NEWNAME=`echo $file| sed -e "s/${1}/${2}/g"`
mv -v "$OLDNAME" "$NEWNAME"
done
不是多次运行ls
才能让文件重命名,而是只运行一次查找并迭代结果