find 指令在 Linux/Mac 電腦的世界,操作起來很方便,針對找的結果,也可以使用 {} 來取代,做進階的處理,但要怎麼對 {} 的字串,再做更新一步的處理?
例如:找到的 .bmp 的檔案,想輸出成 .png ,或取代掉檔案名裡的特定符號。
Using Brace Expansion
:
find . -name "*.in" -exec bash -c 'python script.py "${0%.*}"{.in,.out}' {} \;
Using Shell Parameter Expansion
:
find . -name "*.in" -exec bash -c 'python script.py "find . -name "*.in" -exec bash -c 'python script.py "${0} ${0/.in/.out}"' {} \;
${0/.in/.out}"' {} \;
Result:
python script.py somefile.in somefile.out
To replace the first occurrence of a pattern with a given string, use ${parameter/pattern/string}
:
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
To replace all occurrences, use ${parameter//pattern/string}
:
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(This is documented in the Bash Reference Manual, §3.5.3 “Shell Parameter Expansion”.)
要在 macOS 裡增加 “U_” 的 prefix 的方法:
find . -name “*.png” -type f -exec bash -c ‘mv $0 ${0/\.\//\.\/U_}’ {} \;
直接使用下面的方法,會失敗
find . -type f -exec bash -c 'mv $0 yourPrefix$0' {} \;
詳細用法
Variable expansion / Substring replacement
These constructs have been adopted from ksh.
${var:pos}
Variable var expanded, starting from offset pos.
${var:pos:len}
Expansion to a max of len characters of variable var, from offset pos.
${var/Pattern/Replacement}
First match of Pattern, within var replaced with Replacement.
If Replacement is omitted, then the first match of Pattern is replaced by nothing, that is, deleted.
${var//Pattern/Replacement}
Global replacement. All matches of Pattern, within var replaced with Replacement.
As above, if Replacement is omitted, then all occurrences of Pattern are replaced by nothing, that is, deleted.
stringZ=abcABC123ABCabc echo ${stringZ/abc/xyz} # xyzABC123ABCabc # Replaces first match of 'abc' with 'xyz'. echo ${stringZ//abc/xyz} # xyzABC123ABCxyz # Replaces all matches of 'abc' with # 'xyz'. echo --------------- echo "$stringZ" # abcABC123ABCabc echo --------------- # The string itself is not altered! # Can the match and replacement strings be parameterized? match=abc repl=000 echo ${stringZ/$match/$repl} # 000ABC123ABCabc # ^ ^ ^^^ echo ${stringZ//$match/$repl} # 000ABC123ABC000 # Yes! ^ ^ ^^^ ^^^ echo # What happens if no $replacement string is supplied? echo ${stringZ/abc} # ABC123ABCabc echo ${stringZ//abc} # ABC123ABC # A simple deletion takes place.
${var/#Pattern/Replacement}
If prefix of var matches Pattern, then substitute Replacement for Pattern.
${var/%Pattern/Replacement}
If suffix of var matches Pattern, then substitute Replacement for Pattern.
stringZ=abcABC123ABCabc
echo ${stringZ/#abc/XYZ} # XYZABC123ABCabc
# Replaces front-end match of ‘abc’ with ‘XYZ’.
echo ${stringZ/%abc/XYZ} # abcABC123ABCXYZ
# Replaces back-end match of ‘abc’ with ‘XYZ’.
${!varprefix*}, ${!varprefix@}
Matches names of all previously declared variables beginning with varprefix.
資料來源:
How to substitute string in {} in “find (…) -exec (…) {} \;” bash command?
https://stackoverflow.com/questions/50406662/how-to-substitute-string-in-in-find-exec-bash-command#=
Bash variable substitution on find’s output through exec
https://stackoverflow.com/questions/30481590/bash-variable-substitution-on-finds-output-through-exec
Use current filename (“{}”) multiple times in “find -exec”?
https://stackoverflow.com/questions/12965400/use-current-filename-multiple-times-in-find-exec