Bash

當從 Find ‘-exec’ 呼叫時,流水線化的 Sed 對 Bash 命令替換中找到的文件名不起作用

  • October 30, 2017

在某些情況下,‘find’、‘bash’ 和 ‘sed’ 看起來不像預期的那樣工作。

以下範例應首先創建文件“sample.txt”,然後找到該文件,最後通過“-exec”命令對其進行處理。執行的命令列印找到的文件名、測試樣本和修改的文件名。“sed”命令本身用於將“txt”替換為“TXT”。

touch sample.txt
find ./ -maxdepth 1 -name "*.txt" -exec echo {} $(echo Specimen_before.txt {} Specimen_after.txt |sed -e "s/txt/TXT/g") \;

預期的輸出是:

./sample.txt Specimen_before.TXT ./sample.TXT Specimen_after.TXT

相反,它會產生:

./sample.txt Specimen_before.TXT ./sample.txt Specimen_after.TXT

(該範例還通過反引號 ‘`’ 使用老式命令替換進行了測試,結果相同)

我究竟做錯了什麼?

命令替換find甚至在開始之前執行。實際執行的命令(在替換、擴展和引號刪除等之後)是

find ./ -maxdepth 1 -name *.txt -exec echo {} Specimen_before.TXT {} Specimen_after.TXT ;

如果您需要使用 執行任何花哨的東西(管道或多個命令)-exec,請啟動一個單獨的 shell 來執行此操作:

find . -maxdepth 1 -type f -name '*.txt' \
   -exec sh -c 'printf "%s " "$1"; printf "%s %s %s\n" "before.txt" "$1" "after.txt" | sed "s/txt/TXT/g"' sh {} ';'

引用自:https://unix.stackexchange.com/questions/401384