xargs は -d'\n' を使用する場合は空行を無視します。

xargs は -d'\n' を使用する場合は空行を無視します。

空行を持つことができるファイル入力がありますが、空行をスキップしたいと思います。
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-rxargs

(とにかくxargs特定の例ではあなたのものと同じである必要はありませんfind . -criteria -exec ls -ld {} +)。

私が知る限り、GNUはオプションをサポートするxargs唯一の-d実装であり、nullかどうかにかかわらず、特定のパラメータ値のフィルタリングをサポートしていないのでgrepgrep -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-dxargs

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構文です。

おすすめ記事