问题
I have a folder with a series of files named:
prefix_1234_567.png
prefix_abcd_efg.png
I'd like to batch remove one underscore and the middle content so the output would be:
prefix_567.png
prefix_efg.png
Relevant but not completely explanatory:
- How can I batch rename files using the Terminal?
- Regex to batch rename files in OS X Terminal
回答1:
In your specific case you can use the following bash
command (bash
is the default shell on macOS):
for f in *.png; do echo mv "$f" "${f/_*_/_}"; done
Note: If there's a chance that your filenames start with -
, place --
before them[1]:mv -- "$f" "${f/_*_/_}"
Note: echo
is prepended to mv
so as to perform a dry run. Remove it to perform actual renaming.
You can run it from the command line or use it in a script.
"${f/_*_/_}"
is an application ofbash
parameter expansion: the (first) substring matching pattern_*_
is replaced with literal_
, effectively cutting the middle token from the name.- Note that
_*_
is a pattern (a wildcard expression, as also used for globbing), not a regular expression (to learn about patterns, runman bash
and search forPattern Matching
).
If you find yourself batch-renaming files frequently, consider installing a specialized tool such as the Perl-based rename utility. On macOS you can install it using popular package manager Homebrew as follows:
brew install rename
Here's the equivalent of the command at the top using rename
:
rename -n -e 's/_.*_/_/' *.png
Again, this command performs a dry run; remove -n
to perform actual renaming.
- Similar to the
bash
solution,s/.../.../
performs text substitution, but - unlike inbash
- true regular expressions are used.
[1] The purpose of special argument --
, which is supported by most utilities, is to signal that subsequent arguments should be treated as operands (values), even if they look like options due to starting with -
, as Jacob C. notes.
回答2:
To rename files, you can use the rename
utility:
brew install rename
For example, to change a search string in all filenames in current directory:
rename -nvs searchword replaceword *
Remove the 'n' parameter to apply the changes.
More info: man rename
回答3:
You could use sed:
ls * | sed -e 'p;s@_.*_@_@g' | xargs -n2 mv
result:
prefix_567.png prefix_efg.png
*to do a dry-run first, replace mv
at the end with echo
Explanation:
- e: optional for only 1 sed command.
- p: to print the input to sed, in this case it will be the original file name before any renaming
- @: is a replacement of / character to make sed more readable. That is, instead of using sed s/search/replace/g, use s@search@replace@g
- _.* : the underscore is an escape character to refer to the actual '.' character zero or more times (as opposed to ANY character in regex)
- -n2: indicates that there are 2 outputs that need to be passed on to mv as parameters. for each input from ls, this sed command will generate 2 output, which will then supplied to mv.
回答4:
I had a batch of files that looked like this: be90-01.png and needed to change the dash to underscore. I used this, which worked well:
for f in *; do mv "$f" "`echo $f | tr '-' '_'`"; done
回答5:
you can install rename
command by using brew
. just do brew install rename
and use it.
回答6:
Using mmv
mmv '*_*_*' '#1_#3' *.png
回答7:
try this
for i in *.png ; do mv "$i" "${i/remove_me*.png/.png}" ; done
Here is another way:
for file in Name*.png; do mv "$file" "01_$file"; done
来源:https://stackoverflow.com/questions/24102974/how-to-batch-rename-files-in-a-macos-terminal