カレントディレクトリ配下のfileをtouchしたいとき

結論

こんな感じでxargsを使えばOK

find -name *.cpp | xargs -I {} touch {}

解説

  • このコマンドは、カレントディレクトリ以下のすべての .cpp ファイルを検索し、それらのファイルに対して touch コマンドを実行するもの。
  • findコマンドは、指定された条件に一致するファイルを検索するために使用される。
    • この場合、 -name オプションを使用してファイル名のパターンを指定している。
    • *.cpp は、カレントディレクトリ以下のすべての .cpp ファイルにマッチするように指定されている。
  • | (パイプ)は、前のコマンドの出力を次のコマンドに渡すために使用される。
  • xargs コマンドは、前のコマンドの出力を引数として次のコマンドを実行するために使用される。
  • -I {} オプションは、 xargs に置換文字列 {} を使用するよう指示しています。
  • touch コマンドは、指定されたファイルにタイムスタンプを追加するために使用される。
    • この場合、 xargs によって渡されたファイル名が touch コマンドの引数として使用され、それらのファイルにタイムスタンプが追加される

疑問と回答

awkコマンド使えないの?

これでいける

find -name "*.cpp" | awk '{ system("touch " $0) }'

  • ただし、 xargs コマンドと異なり、 awk コマンドは一度に1つのファイルしか処理できないため、実行時間が長くなる可能性がある。
  • awkコマンド単体ではファイルに対する操作は行なえない。
    • そのためsystem関数を使用して、外部コマンドのtouchを実行することができる
    • findの出力はパスのみなのでその結果は$0に与えられる。($1じゃないよ)

xargsの{}なかったらどうなるの?

  • xargs コマンドを使用する場合、{} を使用することで、xargs が受け取った入力をコマンドライン引数に展開することができる。つまり、 find コマンドの出力に対して、touch コマンドを実行することができる。
  • 一方、{} を使用しない場合、 xargs が受け取った入力を単純にコマンドライン引数として扱う。つまり、findの出力結果複数行をまるっとtouchの引数にすることになってしまう。
    • だから{}が必要。{}があればfindの結果一行ずつをtouchの引数に渡せる。らしい