Io-Redirection
帶有標準輸入/標準輸出重定向的 xargs
我想執行:
./a.out < x.dat > x.ans
對於目錄A中的每個 * .dat文件。
當然,它可以通過 bash/python/whatsoever 腳本來完成,但我喜歡寫性感的單線。我所能達到的只是(仍然沒有任何標準輸出):
ls A/*.dat | xargs -I file -a file ./a.out
但是xargs 中的*-a*不理解 replace-str ‘file’。
謝謝你的幫助。
首先,不要將
ls
輸出用作文件列表。使用外殼擴展或find
. 有關ls+xargs誤用的潛在後果和正確xargs
使用的範例,請參見下文。1.簡單方式:for循環
如果您只想處理 下的文件
A/
,那麼一個簡單的for
循環就足夠了:for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1為什麼不
ls | xargs
呢?這是一個例子,說明如果你在工作中使用
ls
with ,事情可能會變得多麼糟糕。xargs
考慮以下場景:
- 首先,讓我們創建一些空文件:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat $ touch A/mypreciousfile.dat $ touch A/mypreciousfile.dat.ans
- 查看文件並且它們不包含任何內容:
$ ls -1 A/ mypreciousfile.dat mypreciousfile.dat with junk at the end.dat mypreciousfile.dat.ans $ cat A/*
- 使用以下命令執行魔術命令
xargs
:$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
- 結果:
$ cat A/mypreciousfile.dat TRICKED with junk at the end.dat.ans $ cat A/mypreciousfile.dat.ans TRICKED
所以你剛剛設法覆蓋了
mypreciousfile.dat
和mypreciousfile.dat.ans
。如果這些文件中有任何內容,它就會被刪除。2.使用
xargs
:正確的方法find
如果您想堅持使用
xargs
,請使用-0
(null-terminated names) :find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
注意兩點:
- 這樣,您將創建帶有
.dat.ans
結尾的文件;- 如果某些文件名包含引號 ( ),這將中斷。
"
這兩個問題都可以通過不同的 shell 呼叫方式來解決:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. 全部在內部完成
find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
這再次生成
.dat.ans
文件,如果文件名包含"
. 為此,請使用bash
並更改它的呼叫方式:find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;