重命名当前目录和所有子目录中的文件名

时间:2011-01-04 12:34:57

标签: bash unix shell

我在不同的目录和子目录中有4个具有以下名称的文件

tag0.txt, tag1.txt, tag2.txt and tag3.txt 

并希望在所有目录和子目录中将它们重命名为tag0a.txt, tag1a.txt ,tag2a.txt and tag3a.txt

有人可以帮我使用shell脚本吗?

干杯

5 个答案:

答案 0 :(得分:3)

$ shopt -s globstar
$ rename -n 's/\.txt$/a\.txt/' **/*.txt
foo/bar/tag2.txt renamed as foo/bar/tag2a.txt
foo/tag1.txt renamed as foo/tag1a.txt
tag0.txt renamed as tag0a.txt

检查结果后删除-n重命名 - 这是“干运行”选项。

答案 1 :(得分:3)

这当然可以通过find来完成:

find . -name 'tag?.txt' -type f -exec bash -c 'mv "$1" ${1%.*}a.${1##*.}' -- {} \;

答案 2 :(得分:1)

这是一个posix shell脚本(用破折号检查):

visitDir() {
    local file
    for file in "$1"/*; do
            if [ -d "$file" ]; then
                    visitDir "$file";
            else
                    if [ -f "$file" ] && echo "$file"|grep -q '^.*/tag[0-3]\.txt$'; then
                            newfile=$(echo $file | sed 's/\.txt/a.txt/')
                            echo mv "$file" "$newfile"
                    fi
            fi

    done
}

visitDir .

如果您可以使用bashisms,只需将内部IF替换为:

if [[ -f "$file" && "$file" =~ ^.*/tag[0-3]\.txt$ ]]; then
    echo mv "$file" "${file/.txt/a.txt}"
fi

首先检查结果是否符合预期,然后可能删除mv命令前面的“echo”。

答案 3 :(得分:1)

使用可能在您系统上的rename的Perl脚本版本:

find . -name 'tag?.txt' -exec rename 's/\.txt$/a$&/' {} \;

使用rename的二进制可执行版本:

find . -name 'tag?.txt' -exec rename .txt a.txt {} \;

更改第一次出现的“.txt”。由于文件名受-name参数约束,因此不会出现问题。

答案 4 :(得分:0)

这还不错吗?


jcomeau@intrepid:/tmp$ find . -name tag?.txt
./a/tag0.txt
./b/tagb.txt
./c/tag1.txt
./c/d/tag3.txt
jcomeau@intrepid:/tmp$ for txtfile in $(find . -name 'tag?.txt'); do \
 mv $txtfile ${txtfile%%.txt}a.txt; done
jcomeau@intrepid:/tmp$ find . -name tag*.txt
./a/tag0a.txt
./b/tagba.txt
./c/d/tag3a.txt
./c/tag1a.txt

实际上不要在命令中添加反斜杠,如果你这样做,则期望'>'提示下一行。我没有把它放到输出中以避免混淆,但我不希望任何人必须滚动。