xargs -Iをsedと組み合わせる

xargs -Iをsedと組み合わせる

find を使って特定のファイルを見つけ、 cp と sed で xargs を使ってそのファイルを別のフォルダに移動し、名前を変更したいと思います。私はこれをループで行う方法を知っていますが、それは私が望むものではありません。

私は試した:

find ${FOLDER} -iname "*${SOME_STRING}*" | xargs -I {} cp {} $(echo {} | sed 's/ABC/XYZ/g')

これがうまくいかないのはなぜですか、解決策は何ですか?

ベストアンサー1

この試み。必ずしもそうではなく、xargsただfindand です。ファイルは変更されませんが、sedcopy〜するファイルのコピーに使用されるシェルコマンドのリストを印刷します。したがって、印刷されたコマンドが気に入ったら、再実行して最後の行の前#の内容を削除し、シェルにsh -xコマンドを実行させることができます。

find "${FOLDER:-.}" -iname "*${SOME_STRING:-ABC}*" |
sed "
    s/^/'/                      # surround filename with single quotes
    s/$/'/
    h                           # save filename in the sed hold space
    s/ABC/XYZ/g                 # change filename
    H                           # append to hold space (separates with newline)
    g                           # get original and modified from hold
    s/\n/ /g                    # replace the newline with a space
    s/^/cp -i/                  # make it into a copy command
"  #| sh -x                     # optionally pipe to shell

xargsこのアプローチがこの例より優れているのはなぜですか?これは、各ファイルに必要なコマンドに加えて合計3つのプロセス(find、、、および)のみを開始するためです。sedshcp

を使用するには、各ファイル名を処理するために必要な単一のコマンドよりも多くのプロセスがxargs必要です。cp

sedを一度呼び出すと、はるかに効率的に生成されます。みんなcp各ファイル名に対して新しいsedプロセスを呼び出すのではなく、コマンドを実行します。

おすすめ記事