问题
I want to rename a bunch of files using bash, transforming this file pattern:
prefix - name - suffix.txt
Into this one:
name.txt
For that I wrote the following script:
find . -name "*.txt" | while read f
do
mv "${f}" "${f/prefix - /}"
done
find . -name "*.txt" | while read f
do
mv "${f}" "${f/ - suffix/}"
done
It works, but I'd like to perform the renaming using a single loop. Is it possible?
回答1:
Another approach, for fun, using regular expressions:
regex='prefix - (.*) - suffix.txt'
for f in *.txt; do
[[ $f =~ $regex ]] && mv "$f" "${BASH_REMATCH[1]}.txt"
done
Actually, using the simple pattern '*.txt' here has two problems:
- It's too broad; you may need to apply the regex to a lot of non-matching files.
- If there are a lot of files in the current directory, the command line could overflow.
Using find
complicates the procedure, but is more correct:
find . -maxdepth 1 -regex 'prefix - .* - suffix.txt' -print0 | \
while read -d '' -r; do
[[ $REPLY =~ $regex ]] && mv "$REPLY" "${BASH_REMATCH[1]}.txt"
done
回答2:
If you have access to GNU sed
, you could use some regex to perform something like:
for i in *.txt; do mv "$i" "$(echo $i | sed -r 's/([^-]*)\s-\s(.*)\s-\s([^-]*)\.txt/\2.txt/')"; done
回答3:
you could use this:
find . -name "*.txt" -print0 | awk -v RS="\0" -v ORS="\0" '{print $0;sub(/^prefix - /,""); sub(/ - suffix.txt$/,".txt"); print $0; }' | xargs -0 -n 2 mv
which could be written more clearly as:
find . -name "*.txt" -print0 |
awk -v RS="\0" -v ORS="\0" '{
print $0;
sub(/^prefix - /,"");
sub(/ - suffix.txt$/,".txt");
print $0;
}' |
xargs -0 -n 2 mv
回答4:
If you have emacs
installed. You can use the dired
feature.
In bash
:
# open your dir with emacs
emacs /path/to/your/dir
In emacs
:
- Press *%Enter
\.txt$
Enter to mark alltxt
files. - Press %rEnter
.*- \(.*\) -.*
Enter\1.txt
Enter to rename.
来源:https://stackoverflow.com/questions/12031081/renaming-files-with-bash-removing-prefix-and-suffix