STDINから取得した各行に対してシェルコマンドを実行したいと思います。
この場合はxargs mv
。たとえば、次の2行が与えられます。
mfoo foo
mbar bar
私は走りたいです:
xargs mv mfoo foo
xargs mv mbar bar
私は次の戦略を試しましたruby
、awk
、xargs
。しかし、私は何かが間違っています。
のみxargs
:
$ echo "mbar bar\nmbaz baz" | xargs mv
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
渡すawk
:
$ echo "mbar bar\nmbaz baz" | awk '{ system("xargs $0") }'
渡すruby
:
$ echo "mbar bar\nmbaz baz" | ruby -ne '`xargs mv`'
$ ls
cat foo mbar mbaz
質問がいくつかあります:
- 私がしたいことをどうすればいいですか?
- 私が試すたびに何が間違っていますか?
- 私がやろうとしていることを「考える」より良い方法はありますか?
xargs
私は特に次のことがうまくいくので、やりたいことがうまくいかないという事実に混乱しています。
$ echo "foo\nbar" | xargs touch
$ ls
bar foo
答え1
echo "mbar bar\nmbaz baz" | xargs mv
何が起こっているかを確認するには、xargs
このオプションを使用する必要があります。-t
したがって、上記の場合に を使用して呼び出すと、次のxargs
よう-t
な内容が表示されます。
mv mbar bar mbaz baz
したがって、これは明らかに正しくありません。空腹のワニのように、パイプを介してxargs
供給されるすべてのパラメータを食べますecho
。したがって、crocのパラメータリリースを制限する方法が必要です。行ごとに要求するため、-l
または-L
for POSIXオプションが必要です。
echo "mbar bar\nmbaz baz" | xargs -l -t mv
POSIX方式:
echo "mbar bar\nmbaz baz" | xargs -L 1 -t mv
mv mbar bar
mv mbaz baz
これがあなたが望むものです。ファタイ
答え2
次のように行くことができます:
echo -e "foo bar\ndoo dar" | xargs -n 2 mv
ファイルから読む:
cat lines.txt | xargs -n 2 mv
または
xargs -a lines.txt -n 2 mv
答え3
xargs
期待どおりに動作しない場合があります。この質問に関する@MichaelHomerのコメントを参照してください。
xargs mv mfoo foo
入力を待って入力された各行に対してmfoo foo $x_1 $x_2 $x_3...
mvを実行します。$x_n
@マイケルホーマー
これを読むと確認できます。xargs
マニュアルページ:
説明
xargs ユーティリティは、標準入力からスペース、タブ、改行、およびファイルの末尾で区切られた文字列を読み取り、これらの文字列を引数として使用してユーティリティを実行します。
xargs
実際、最初の引数として指定されたコマンドラインユーティリティに引数が指定された場合、改行は無視されるように見えます。たとえば、改行文字に何が起こるかを見てみましょう。
$ echo "foo bar\ncat dog"
foo bar
cat dog
$ echo "foo bar\ncat dog" | xargs echo
foo bar cat dog
この動作は次のように制御できます。-n
バナー:
-n 数値
ユーティリティが呼び出されるたびに、標準入力から取得される最大引数の数を設定します。
前の例に戻り、xargs
2つのパラメータのみを取り出して終了するには、次のようにします。@ddnomadのアプローチ:
$ echo "foo bar\ncat dog" | xargs -n 2 echo
foo bar
cat dog
また、Rakesh Sharmaの回答のコメントに示すように、BSDではxargs
フラグを使用して読み取る回数を指定できます-L
。マニュアルページから:
-Lサイズ
このユーティリティは、読み取った各番号軸に対して呼び出されます。 EOF に到達して
読み取った行数より少ない場合は、使用可能な行としてユーティリティが呼び出されます。
テストに役立つ-t
スイッチもあります。
例をもう一度見てみると、次のすべての方法が機能しますが、この例の目的は、2番目の例の方が優れています。
$ echo "foo bar\ncat dog" | xargs -n 2 echo
foo bar
cat dog
$ echo "foo bar\ncat dog" | xargs -L 1 echo
foo bar
cat dog
マニュアルページの注意事項:
-Lおよび-nオプションは相互に排他的です。提供された最後のオプションが使用されます。
答え4
xargsを使用しない非常に単純なソリューションがあります。
この関数を定義します。
$ mv2() { while (($# >1 )); do echo mv "$1" "$2"; shift 2; done; }
次に、必要なファイル名のリストを使用して呼び出します(改行は必要ありません)。
$ mv2 mbar bar mbaz baz
mv mbar bar
mv mbaz baz
エコーを削除し、機能が実際に機能するようにします。