空行を持つことができるファイル入力がありますが、空行をスキップしたいと思います。
grep /trを使用し、出力をxargsにパイピングする必要がないソリューションを見つけようとしています。
次のxargオプションを使用してください
-アル字型引数なしでコマンドを実行したくありません。 -d '\n'新しい行は区切り記号です。
echo コマンドを使用します。
echo "" | xargs -r -d'\n' -I {} echo "test '{}'"
出力:
test ''
空行で構成されたファイルを使用するコマンド:
xargs -a /tmp/test.txt -r -d'\n' -I {} echo "test '{}'"
出力:
test ''
test ''
test ''
上記のようにgrepを使用できますが、xargsのみを使用して実行できるかどうか疑問に思います。
grepの例(動作中):
grep -v -e '^$' /tmp/test.txt | xargs -r -d'\n' -I {} echo "test '{}'"
ベストアンサー1
-r
-I
空の要素を無視する代わりに、入力に要素がないときにコマンドを一度実行しないでください(BSDではありませんが)-J
。必須ではありません。
あなたは通常-r
この理由でそれをしたいです。
find . -criteria -print0 | xargs -0 ls -ld
何も見つからない場合は、引数なしで実行さfind
れ、ls -d
表示されます.
。
だからあなたは欲しい:
find . -criteria -print0 | xargs -r0 ls -ld
何も見つからないとls
まったく実行されませんfind
。
と両方ともGNU拡張-r
です(再び、移植性が低下します)。 FreeBSD と NetBSD を含む一部の BSD のデフォルト動作です (これは POSIX と互換性がありませんが)。-0
-d
-r
xargs
(とにかくxargs
特定の例ではあなたのものと同じである必要はありませんfind . -criteria -exec ls -ld {} +
)。
私が知る限り、GNUはオプションをサポートするxargs
唯一の-d
実装であり、nullかどうかにかかわらず、特定のパラメータ値のフィルタリングをサポートしていないのでgrep
(grep -v '^$'
またはLC_ALL=C grep .
)を使用するのが正しいアプローチです。
-a
たとえば、コマンドのstdinを変更せずにkshスタイルのプロセス置換(ksh、zsh、bash)をサポートするシェルを使用するなど、他のGNU拡張機能を引き続き使用したい場合は、次のようにします。
xargs -rd '\n' -a <(grep -v '^$' test.txt) cmd --
xargs -d '\n' -I{} -a <(grep -v '^$' test.txt) cmd -- {}
(rc、akanga、es、fish、yashシェルは機能は同じですが構文は異なります)。
-0
のよう-d '\0'
なので衝突することに注意してください-d '\n'
。d
希望のリミッターを選択してください。後者が-0 -d '\n'
最後なので優先順位があります。
-0
コマンドパラメーターまたはファイルパスには現れないシングルバイト値であるため、好ましい区切り文字です。-0
、現在他の多くの実装(ほとんどのBSD、Solaris、busybox、toybox、ast-open実装を含む)-d
に見られるものとは対照的です。サポートされていない実装(つまり、GNUを除くすべての実装)xargs
の場合は、次のものを使用できます。xargs
-d
xargs
tr '\n' '\0' | xargs -0 ...
GNUの代わりに:
xargs -d '\n' ...
を使用している場合は、使用する代わりzsh
に、xargs
次のことができます。
for arg ( ${(f)"$(<test.txt)"} ) cmd -- $arg
パラメータf
拡張フラグは改行に分割され、${...}
引用符がないため空の要素が削除されます。
そしてbash
:
readarray -t args < test.txt &&
for arg in "${args[@]}"; do
[ -z "$arg" ] || cmd -- "$arg"
done
引用符なしの配列拡張機能を使用してヌル削除を実行することもできますが、引用符なしの引数拡張機能によっても実行されるワイルドカードと分割を無効にする必要があります。
IFS=; set -o noglob
readarray -t args < test.txt &&
for arg in ${args[@]}; do
cmd -- "$arg"
done
次のこともできます。
while IFS= read <&3 -r arg || [ -n "$arg" ]; do
[ -z "$arg" ] || cmd -- "$arg" 3<&-
done 3< test.txt
これは標準sh
構文です。