回答:
受け入れ答えは正しい考えを持っていますが、キーは通過させることであることを意味する、スイッチを「一度出力の行ごとのコマンドを実行します。」xargs
-n1
cat file... | xargs -n1 command
または、単一の入力ファイルの場合、パイプをcat
完全に回避して次のように実行できます。
<file xargs -n1 command
xargs
しない機能も興味深いものです。標準入力に空白以外の文字が含まれていない場合は、コマンドを実行しないでください。通常、入力がない場合でもコマンドは1回実行されます。このオプションはGNU拡張機能です。stdin
--no-run-if-empty
-r
command
か?
Bashまたはその他のBourneスタイルのシェル(ash、ksh、zsh、…):
while read -r line; do command "$line"; done
read -r
標準入力から1行を読み取ります(バックスラッシュread
を-r
解釈せず、必要ありません)。したがって、次のいずれかを実行できます。
$ command | while read -r line; do command "$line"; done
$ while read -r line; do command "$line"; done <file
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done
ところうまくいきませんでした。while
ループにパイプされたファイルで動作し、tail -f
でのみ動作しgrep
、で動作しましたが、両方のパイプでは動作しませんでした。与えるオプションは、それが働かせたgrep
--line-buffered
command | while read -r line; do echo "$line" | command ; done
Keithに同意します。xargsはこのジョブの最も一般的なツールです。
私は通常、3段階のアプローチを使用します。
小さくて速い方法がありますが、この方法はほとんど常に機能します。
簡単な例:
ls |
grep xls |
awk '{print "MyJavaProg --arg1 42 --arg2 "$1"\0"}' |
xargs -0 bash -c
最初の2行で作業するファイルを選択し、awkは実行するコマンドといくつかの引数を含む素敵な文字列を準備します。$ 1はパイプからの最初の列入力です。そして最後に、xargsがこの文字列をbashに送信して、実行するようにします。
それは少しやり過ぎですが、このレシピは非常に柔軟なので、多くの場所で私を助けました。
xargs -0
あなたのawkのprint文があるべきよう、レコードセパレータとしてnullバイトを使用していますprintf("MyJavaProg --args \"%s\"\0",$1)
awk
ている場合はパターンマッチを実行して、grep
たとえばスキップすることができます。ls | awk '/xls/ {print...
GNU Parallelは、そのようなタスク用に作られています。最も簡単な使用法は次のとおりです。
cat stuff | grep pattern | parallel java MyProg
詳細については、紹介ビデオをご覧ください:http : //www.youtube.com/watch?v=OpaiGYxkSuQ
cat
ので、ここでgrep
直接ファイルを読むことができます
< stuff grep pattern
、grep pattern stuff
リダイレクトや猫がまったく必要ないからです。それでも、それは重大あなたの引数を変更しないと、あなたはそれが常にで始まるパイプで物事を使用することが明確だと思うならばcat
、あなたにパワー、その後、
また、while read
フィッシュシェルでループします(フィッシュタグを使用したことを考慮して、フィッシュシェルが必要であると想定しています)。
command | while read line
command $line
end
注意すべき点はほとんどありません。
read
-r
最も一般的なユースケースを簡単にするために、引数を取らず、バックスラッシュを解釈しません。$line
bashとは異なり、fishは変数をスペースで区切らないため、引用符で囲む必要はありません。command
それ自体は構文エラーです(プレースホルダー引数のそのような使用をキャッチするため)。それを実際のコマンドに置き換えます。while
とペアにする必要はありませんか?do
done
end
入力引数をコマンドラインに正確に挿入する場所を制御する必要がある場合、またはそれを数回繰り返す必要がある場合は、を使用する必要がありますxargs -I{}
。
another_folder
現在のディレクトリのサブフォルダーをミラー化する空のフォルダー構造を作成します。
ls -1d ./*/ | xargs -I{} mkdir another_folder/{}
例2
stdinからのファイルリストに操作を適用します。この場合.html
、.bak
拡張子を追加して各ファイルのコピーを作成します。
find . -iname "*.html" | xargs -I{} cp {} {}.bak
-I replstr
Execute utility for each input line, replacing one or more occurrences of
replstr in up to replacements (or 5 if no -R flag is specified) arguments
to utility with the entire line of input. The resulting arguments, after
replacement is done, will not be allowed to grow beyond 255 bytes; this is
implemented by concatenating as much of the argument containing replstr as
possible, to the constructed arguments to utility, up to 255 bytes. The
255 byte limit does not apply to arguments to utility which do not contain
replstr, and furthermore, no replacement will be done on utility itself.
Implies -x.
Linux xargs
manページ:
-I replace-str
Replace occurrences of replace-str in the initial-
arguments with names read from standard input. Al‐
so, unquoted blanks do not terminate input items;
instead the separator is the newline character.
Implies -x and -L 1.
潜在的にサニタイズされていない入力を処理する場合、実行する前に(特に人のメールボックスのクリーニングのような破壊的なものである場合)視覚的に検査するために、ジョブ全体を1行ずつ「スペルアウト」するのが好きです。
だから私がやっていることは、パラメータのリスト(つまり、ユーザー名)を生成し、次のように1行ごとに1つの方法でファイルにフィードすることです:
johndoe
jamessmith
janebrown
次に、リストを開き、vim
検索でマングルし、次のように、実行する必要がある完全なコマンドのリストを取得するまで式を置き換えます。
/bin/rm -fr /home/johndoe
/bin/rm -fr /home/jamessmith
このように正規表現が不完全な場合、どのコマンドに潜在的な問題があるかがわかります(例:)/bin/rm -fr johnnyo connor
。この方法で正規表現を元に戻し、より信頼性の高いバージョンで再試行できます。名前のマングリングはこのことで有名です。なぜなら、ゴッホ、オコナーズ、セントクレア、スミスウェッソンなどのエッジケースをすべて処理するのは難しいからです。
でset hlsearch
これを行うと便利です。vim
すべての一致が強調表示されるため、一致しない場合や意図しない方法で一致する場合に簡単に見つけることができます。
正規表現が完璧になり、テスト/考えられるすべてのケースをキャッチしたら、通常はそれをsed式に変換して、別の実行のために完全に自動化できるようにします。
入力行数が原因で視覚的な検査を行えない場合は、コマンドを実行する前に画面(またはログ)にエコーすることを強くお勧めします。失敗する。その後、元の正規表現に戻ってもう一度調整できます。
私はこれが好きです-複数行のコマンドと明確なコードを許可する
find -type f -name filenam-pattern* | while read -r F
do
echo $F
cat $F | grep 'some text'
done
printf "foo bar\nbaz bat" | xargs echo whee
になりwhee foo bar baz bat
ます。-L
または-n
オプションを追加しますか?