這個網站向xargs
命令提供一個-J
選項,使得能夠將標準輸入傳遞到命令參數處的所需位置:
find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/
但在一個GNU xargs 手冊頁該選項不存在。
對於接受此操作的命令,執行此操作的方法是什麼?
答案1
我不確定這是否是您所期望的,但在 BSD 世界(例如 macOS)中,-I
它們-J
將多「行」傳遞給命令的方式有所不同。例子:
$ ls
file1 file2 file3
$ find . -type f -print0 | xargs -I % rm %
rm file1
rm file2
rm file3
$ find . -type f -print0 | xargs -J % rm %
rm file1 file2 file3
因此,對於-I
, xargs 將為單獨傳遞給它的每個元素運行命令。使用 時-J
, xargs 將執行一次命令並連接所有元素並將它們作為參數傳遞在一起。
某些命令(例如rm
或 )mkdir
可以採用多個參數並對其進行操作,就像傳遞單個參數並多次運行它們一樣。但某些應用程式可能會發生變化,具體取決於您向它們傳遞參數的方式。例如tar
.您可以建立 tar 文件,然後向其中新增文件,也可以透過一次性向其中新增所有文件來建立 tar 文件。
$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %
答案2
如果這是-J
BSD 版本的標誌,xargs
我不相信 GNU 有完全相同的選項xargs
。-J
替換單一出現的複製字串(例如%
)每行都透過標準輸入進入。 GNU 版本有一個相似的不過,選項:-I
1。但是,您可以使用複製字串多次使用該標誌。
對於是否有一個或多個命令呼叫並不重要的用例,您應該能夠使用 GNUxargs -I
作為直接替代品。但你的範例使用了rsync
,我確信你不希望多次呼叫它。
那麼你最好的行動方案是考慮從find
and the-exec
或-execdir
行動開始的替代方案。這些有兩種變體。一種類似 GNU -I
,另一種類似 BSD -J
。看看這些例子......
# Note the escaping of ';'
$ find /tmp -name '*.txt' -exec echo {} \;
/tmp/a.txt
/tmp/b.txt
..
/tmp/z.txt
現在將其與此進行比較:
$ find /tmp -name '*.txt' -exec echo {} +
/tmp/a.txt /tmp/b.txt .. /tmp/z.txt
兩者之間的唯一區別是哪個“修飾符”出現在末尾,+
或者;
。
1更令人困惑的是 BSD 版本也有,-I
而且它的功能-J
與 GNU相似-I
!但這-I
會受到其他標誌的影響,並且很可能不是您正在尋找的。