回答:
使用する必要はありません xargs
:
for file in $(grep <some-pattern> <filelist>); do scp $file <remote>; done;
どこで
<some-pattern>
あなたの grep
パターン <filelist>
ファイルのリストです <remote>
あなたの遠隔地は scp
コマンド の for
ループは、によって生成された各行を反復します。 grep
そしてこれをに渡す $file
間で実行されたコマンドで再利用できます。 do
そして done
。
また見なさい: 上級Bashスクリプトガイド: - ループ
grep
ファイルをpingしますか?今は何も考えられませんが、Gillesの答えはいずれにしても優れています。
1行に1つの名前でファイル名のリストを反復するには、いくつかの方法があります。
ファイルをシェル内でファイル名のリストに変換するには、コマンド置換を使用してください。コマンド置換の結果を単語に分割する必要があるため、コマンド置換を二重引用符で囲むことはできないため、注意が必要です。グロビングをオフにして設定する必要があります IFS
改行で単語を分割するだけです。
set -f; IFS='
'
scp -- $(…) remote.example.com:
使用 read
ループ内でファイル名を処理するための組み込み関数。繰り返しますが、注意が必要です。 read
バックスラッシュを扱います $IFS
特別な文字です。
… | while IFS= read -r x; do scp -- "$x" remote.example.com: done
あなたはGNU xargsを使うことができますが、xargsは奇妙に引用されたフォーマットで入力を期待するので注意深く踏まなければなりません。合格する必要があります -d '\n'
改行を入力区切り文字として明示的に選択し、空白文字と特殊文字の動作をオフにするオプション \'"
。
… | xargs -d '\n' -I {} scp {} remote.example.com:
の唯一の利点 xargs
これは、コマンドラインの長さの制限まで、複数の引数を1回の呼び出しにまとめることができますが、引数が最後にコマンドに渡される場合にのみ機能します。あなたはへの中間呼び出しを通してそれを達成することができます sh
しかし、それはトラブルの価値があることはめったにありません。
… | xargs -d '\n' sh -c 'scp -- "$@" "$0"' remote.example.com:
より簡単な使い方 xargs
改行ではなくNULLで区切られたリストを取得することです。これには -0
これはGNU xargsと最近の* BSDでサポートされています。上記のように、引数を最終的でない位置に押し込むには、少し作業が必要です。
… | tr '\n' '\0' | xargs -0 sh -c 'scp -- "$@" "$0"' remote.example.com:
の …
一部は grep NAME_REGEXP /path/to/filenames.list
正規表現を使ってファイル名をフィルタリングするつもりなら。ファイルの内容をフィルタリングするつもりなら、上記のテクニックの1つを使ってファイル名を grep
例えば、
set -f; IFS='
'
scp -- $(grep -l CONTENT_REGEXP -- $(cat /path/to/filenames.list)) \
remote.example.com:
シェルの問題を回避するもう1つの可能性は使用することです rsync
そしてその --files-from
オプション。ファイル名はすべて現在のディレクトリを基準にしています。
grep NAME_REGEXP /path/to/filenames.list |
rsync -a --files-from - . remote.example.com:
つかいます read
行ごとに出力を解析する( https://stackoverflow.com/a/7039208 ;
grep <some-pattern> <filelist> | while read file; do scp $file <remote>; done;