find指令找到的結果的字串處理

Posted in :

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 "${0} ${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

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *