web-dev-qa-db-ja.com

xargsはスペースではなく改行で分割

これが私の問題です

$ echo 'for i in $@; do echo arg: $i; done; echo DONE' > /tmp/test.sh
$ echo "ac\nbc\ncc\n" | xargs bash /tmp/test.sh 
arg: ac
arg: bc
arg: cc
DONE

これは私が期待することですが、

$ echo "ac s\nbc s\ncc s\n" | xargs -d \n bash /tmp/test.sh
arg: ac
arg: s
arg: bc
arg: s
arg: cc
arg: s
DONE

出力はすべきではありませんか?

arg: ac s
arg: bc s
arg: cc s
DONE

Xargsで2番目の出力を取得するにはどうすればよいですか?

19
fakedrake

試してください:

printf %b 'ac s\nbc s\ncc s\n' | xargs -d '\n' bash /tmp/test.sh

\nに渡された-dの引用を怠ったため、\nではなくnが区切り文字としてxargsに渡された-シェルは「ate」 \(シェルが引用符で囲まれていない文字列を解析する場合、\はエスケープ文字として機能します。通常の文字が\-この場合はnに続く場合、その通常の文字のみが使用されます) 。

また、スクリプト内で$@を二重引用符で囲む(またはin "$@"の部分を完全に省略する)ことは、@ glennジャックマンのアドバイスにも注意してください。

また:xargs -dはGNU拡張であり、たとえば、FreeBSD/macOSでは機能しません。そこで機能させるには、@を参照してください。 glenn jackmanのxargs -0ベースのソリューション。


文字列の\nインスタンスがallBourne-likeの改行として解釈されるようにするために、printfではなくechoを使用していることに注意してくださいシェル:
bashおよびksh[1]echoのデフォルトは、\ベースのエスケープシーケンスを解釈しない(これを実現するには-eを使用する必要があります)-zshdashなどのPOSIXに厳密に準拠したシェルとは異なります。
したがって、printfの方が移植性が高くなります。

[1]マニュアルによると、kshechobuiltinは、ホストプラットフォームの外部echoutility;これはプラットフォームによって異なる可能性がありますが、LinuxおよびBSD/macOSの実装では、デフォルトで\エスケープシーケンスを解釈しません。

16
mklement0

シェルスクリプトは"$@"ではなく$@を使用する必要があります

http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters を参照してください


私のマシンのxargsマニュアルで私は見ます:

xargsは、blanks [...]または改行で区切られた標準入力から項目を読み取ります

(強調鉱山)

したがって:

$ echo $'ac s\nbc s\ncc s\n' | xargs bash /tmp/test.sh  
arg: ac
arg: s
arg: bc
arg: s
arg: cc
arg: s
DONE

$ printf "%s\0" "ac s" "bc s" "cc s" | xargs -0 bash /tmp/test.sh
arg: ac s
arg: bc s
arg: cc s
DONE

前者を使用すると、以下と同等になります。

bash /tmp/test.sh ac s bc s cc s

null-separatorの使用との比較

bash /tmp/test.sh "ac s" "bc s" "cc s"

データに空白が含まれている場合は、xargsの区切り文字を明確にする必要があります。

$ printf "%s\n" "ac s" "bc s" "cc s" | xargs -d $'\n' bash /tmp/test.sh
arg: ac s
arg: bc s
arg: cc s
DONE

$ echo $'ac s\nbc s\ncc s\n' | xargs -d $'\n' bash /tmp/test.sh  
arg: ac s
arg: bc s
arg: cc s
arg:  
DONE

最後の場合の追加の引数に注意してください。echoはすでに改行を追加しているため、echo -nを使用しない限り、追加の引数は必要ありません。

5
glenn jackman