將 xargs -I 與 sed 結合起來

將 xargs -I 與 sed 結合起來

我想使用 find 查找某些文件,然後使用 xargs 與 cp 和 sed 將這些文件移動到另一個資料夾並重命名。我知道如何循環執行此操作,但這不是我想要的。

我試過:

find ${FOLDER} -iname "*${SOME_STRING}*" | xargs -I {} cp {} $(echo {} | sed 's/ABC/XYZ/g')

為什麼這不起作用以及解決方案是什麼?

答案1

嘗試這個。它不需要xargs,只需find和。它不會更改任何文件,但是sedcopy將要列印用於複製檔案的 shell 命令清單。因此,如果您喜歡它列印的命令,那麼您可以再次運行它並刪除最後一行#之前的內容sh -x,然後讓 shell 執行命令。

find "${FOLDER:-.}" -iname "*${SOME_STRING:-ABC}*" |
sed "
    s/^/'/                      # surround filename with single quotes
    s/$/'/
    h                           # save filename in the sed hold space
    s/ABC/XYZ/g                 # change filename
    H                           # append to hold space (separates with newline)
    g                           # get original and modified from hold
    s/\n/ /g                    # replace the newline with a space
    s/^/cp -i/                  # make it into a copy command
"  #| sh -x                     # optionally pipe to shell

xargs為什麼這種方法比本例更好?因為除了每個檔案所需的命令之外,此方法總共只啟動 3 個進程(findsed和)。shcp

要使用xargs,處理每個檔案名稱將需要比單一所需cp命令更多的進程。

讓 sed 的一次調用產生的效率高得多全部命令cp,而不是為每個檔案名稱呼叫一個新sed進程。

答案2

使用 GNU Parallel 看起來像這樣:

find ${FOLDER} -iname "*${SOME_STRING}*" |
  parallel cp {} '{= s/ABC/XYZ/g =}'

{= =} 建構包含更改 $_ 的 Perl 表達式。

優點之一是 GNU Parallel 會做正確的事情,即使您有名為:

My brother's 12" records worth >100$.txt

或類似的恐怖:

touch Y-"$(perl -e 'print pack("c*",1..9,11..46,48..255)')"

相關內容