在一个目录中有多个以fgh开头的文件,例如:
fghfilea
fghfileb
fghfilec
我想将它们全部重命名为以前缀jkl开头。是否有一个单独的命令来执行该操作,而不是逐个重命名每个文件?
在一个目录中有多个以fgh开头的文件,例如:
fghfilea
fghfileb
fghfilec
我想将它们全部重命名为以前缀jkl开头。是否有一个单独的命令来执行该操作,而不是逐个重命名每个文件?
当前回答
(在我的Mac上)用Ruby做这个要容易得多。下面是两个例子:
# for your fgh example. renames all files from "fgh..." to "jkl..."
files = Dir['fgh*']
files.each do |f|
f2 = f.gsub('fgh', 'jkl')
system("mv #{f} #{f2}")
end
# renames all files in directory from "021roman.rb" to "021_roman.rb"
files = Dir['*rb'].select {|f| f =~ /^[0-9]{3}[a-zA-Z]+/}
files.each do |f|
f1 = f.clone
f2 = f.insert(3, '_')
system("mv #{f1} #{f2}")
end
其他回答
这是如何使用sed和mv一起执行重命名:
for f in fgh*; do mv "$f" $(echo "$f" | sed 's/^fgh/jkl/g'); done
根据下面的评论,如果文件名中有空格,则可能需要在返回文件名的子函数周围加上引号,以便将文件移动到:
for f in fgh*; do mv "$f" "$(echo $f | sed 's/^fgh/jkl/g')"; done
(在我的Mac上)用Ruby做这个要容易得多。下面是两个例子:
# for your fgh example. renames all files from "fgh..." to "jkl..."
files = Dir['fgh*']
files.each do |f|
f2 = f.gsub('fgh', 'jkl')
system("mv #{f} #{f2}")
end
# renames all files in directory from "021roman.rb" to "021_roman.rb"
files = Dir['*rb'].select {|f| f =~ /^[0-9]{3}[a-zA-Z]+/}
files.each do |f|
f1 = f.clone
f2 = f.insert(3, '_')
system("mv #{f1} #{f2}")
end
这个脚本为我工作递归重命名目录/文件名可能包含空白:
find . -type f -name "*\;*" | while read fname; do
dirname=`dirname "$fname"`
filename=`basename "$fname"`
newname=`echo "$filename" | sed -e "s/;/ /g"`
mv "${dirname}/$filename" "${dirname}/$newname"
done
注意sed表达式,它在这个例子中替换了所有;有空间。这当然要根据具体需要进行更换。
使用find, xargs和sed:
find . -name "fgh*" -type f -print0 | xargs -0 -I {} sh -c 'mv "{}" "$(dirname "{}")/`echo $(basename "{}") | sed 's/^fgh/jkl/g'`"'
它比@nik的解决方案更复杂,但它允许递归地重命名文件。例如,结构,
.
├── fghdir
│ ├── fdhfilea
│ └── fghfilea
├── fghfile\ e
├── fghfilea
├── fghfileb
├── fghfilec
└── other
├── fghfile\ e
├── fghfilea
├── fghfileb
└── fghfilec
会变成这样,
.
├── fghdir
│ ├── fdhfilea
│ └── jklfilea
├── jklfile\ e
├── jklfilea
├── jklfileb
├── jklfilec
└── other
├── jklfile\ e
├── jklfilea
├── jklfileb
└── jklfilec
使它与xargs一起工作的关键是从xargs调用shell。
在文件列表上运行sed表达式的通用脚本(将sed解决方案与重命名解决方案结合在一起):
#!/bin/sh
e=$1
shift
for f in $*; do
fNew=$(echo "$f" | sed "$e")
mv "$f" "$fNew";
done
通过向脚本传递一个sed表达式来调用,然后是任何文件列表,就像rename的一个版本:
script.sh 's/^fgh/jkl/' fgh*