將通配符 * 傳遞給(bash?)腳本

將通配符 * 傳遞給(bash?)腳本

我想從中等大小的文字檔案集合中刪除所有看起來像“@n”、“@R”等的顏色代碼。

因此,在名為「remove_cc」的檔案中,我寫了以下內容:

sed -ie 's/@r//g' $1
sed -ie 's/@g//g' $1
sed -ie 's/@y//g' $1
sed -ie 's/@b//g' $1
sed -ie 's/@m//g' $1
sed -ie 's/@c//g' $1
sed -ie 's/@n//g' $1
sed -ie 's/@R//g' $1
sed -ie 's/@G//g' $1
sed -ie 's/@Y//g' $1
sed -ie 's/@B//g' $1
sed -ie 's/@M//g' $1
sed -ie 's/@C//g' $1
sed -ie 's/@N//g' $1
sed -ie 's/@W//g' $1
sed -ie 's/@K//g' $1

無論如何,如果我像這樣使用它,腳本會非常有效:./remove_cc file.txt

但是,如果我輸入./remove_cc *.txt一個包含許多 txt 檔案的資料夾,並且我想在其中執行腳本,則它不會執行任何操作。 ./remove_cc *同樣無效。

有沒有辦法解決這個問題,使其有效?

答案1

當您鍵入 時./remove_cc *,shell 將其變更為./remove_cc file1.txt file2.txt file3.txt etc,並以這種方式執行您的腳本。您的腳本僅查看$1第一個參數(file1.txt)。

最通用的方法是依序循環每個參數。 "$@"展開為所有參數的列表,我們可以使用for它們來循環。

for n in "$@" ; do
    sed -ie 's/@r//g' "$n"
    ...
done

在這種特殊情況下,由於sed將採用多個文件名,因此您可以簡化:

sed -ie 's/@r//g' "$@"

請注意,編寫 shell 腳本時注意引號很重要。例如,如果沒有引號,腳本將無法處理名為My Text File.txt.

答案2

只需使用

 for x in *
 do
     ./remove_cc $x
 done

順便說一句,您可以將所有 sed 組合在一行中

sed -i \
    -e 's/@r//g' -e 's/@g//g' -e 's/@y//g' -e 's/@b//g' \
    -e 's/@m//g' -e 's/@c//g' -e 's/@n//g' -e 's/@R//g' \
    -e 's/@G//g' -e 's/@Y//g' -e 's/@B//g' -e 's/@M//g' \
    -e 's/@C//g' -e 's/@N//g' -e 's/@W//g' -e 's/@K//g' \
    $1

您也可以使用分號連線 sed 指令:

sed -i -e 's/@r//g;s/@g//g;s/@y//g' $1

或只使用字元列表

sed -i -e s/@[rgbcmyRGBCMY]//g $1

或者

 sed -i -e s/@[rgbcmyRGBCMY]//g *

(一定要檢查我已經把所有的信都放好了)

答案3

使用"$@"而不是$1.或引用通配符:

$ bash -c 'echo $1' 'some command' '*'
file1 file2
$ bash -c 'echo "$@"' 'some command' *
file1 file2

答案4

如果您不想更改腳本,您也可以透過執行以下命令來使用 xargs(考慮到您擁有它或它在您的平台上可用):

ls *.txt | xargs -L1 ./remove_cc

xargs 是一個實用程序,它接受 stdin 並將其轉換為要運行的命令上的命令參數。它具有 -L 標誌,用於限制單次執行中使用的輸入行數。

相關內容