Files

檢查文件是否存在後如何將文件名列表傳遞給xargs?

  • October 29, 2018

我有一個命令 ( command1),它返回如下文件名列表

/consumer/a.txt
/consumer/b.txt
/consumer/doesnotexist.txt

當我管道輸出時,command1 | xargs command2 command2如果其中一個文件不存在,則會拋出異常。

如何在管道傳輸之前刪除不存在的文件command2?我期待著一些東西

command1 | xargs remove_nonexistant_files | xargs command2

command2應該收到

/consumer/a.txt
/consumer/b.txt

作為輸入。

command1 |
xargs sh -c 'for p do [ -f "$p" ] && printf "%s\n" "$p"; done' sh |
xargs command 2

中間的額外位是另一個xargs簡短腳本的呼叫,它基本上只是循環其給定的命令行參數並列印與現有正常文件(或正常文件的符號連結)相對應的路徑名。然後將這些現有路徑名傳遞到管道的最後一部分。

這假定所有路徑名都沒有嵌入的換行符、空格和製表符。

假設command1以預期的格式輸出列表xargs,您可以定義:

existing_plain_readable_files_only() {
 perl -le "for (@ARGV) {
   if (-f && -r) {s/'/'\\\\''/g; print qq('\$_')}
 }" -- "$@"
}

並將其用作:

command1 | xargs existing_plain_readable_files_only | xargs command2

在這裡,我們僅將perl-f運算符用於正常文件(不是目錄、設備、管道……)和-r使用者可讀的文件(假設command2將要閱讀它們),並且我們使用單引號,除了單引號字元本身用 . 轉義\

這是一種同時xargs受到 shell 支持的引用,這意味著您還可以使用該函式來處理包含任意文件列表的 shell 數組:

eval "array2=($(existing_plain_readable_files_only "${array1[@]}"))"

(這裡假設ksh93, zsh, bash,mkshyash貝殼)。

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