1つのコマンドで異なるフォルダにある複数のファイルを変更しますか?

1つのコマンドで異なるフォルダにある複数のファイルを変更しますか?

abc.txt私のフォルダ/etc/zyz/と複数のサブフォルダにファイルがあります。/etc/zyz-1/ /etc/zyz-2/

echoコマンドを使用してフォルダ内のすべてのファイル(すべて名前付き)を変更するにはどうすればよいですか?一部のシステムにはフォルダが2つしかあり、他のシステムには10を超えるフォルダがあります。abc.txt/etc/zyz

私が実行したいコマンドの例

echo 'New line data' >> abc.txt

abc.txt < /dev/null

答え1

次のツリーが与えられたとき(空のabc.txt):

.
├── zyz
│   └── abc.txt
├── zyz-1
│   └── abc.txt
└── zyz-2
    └── abc.txt

次のコマンドを使用して、すべてのabcファイルを一覧表示できます。

$ echo zyz*/abc.txt
  zyz-1/abc.txt zyz-2/abc.txt zyz/abc.txt

tee -aこれらすべてのファイルにいくつかの入力ストリームを同時に追加できます。

$ echo 'New line data' | tee -a zyz*/abc.txt
  New line data

2回実行すると、各abc.txtに2行が含まれます。

$ cat zyz/abc.txt
  New line data
  New line data
$ cat zyz-1/abc.txt
  New line data
  New line data
$ # ...

これを消去するには、次のようにします。

$ </dev/null tee zyz*/abc.txt

または

$ : | tee zyz*/abc.txt

find -exec(短い名前を持つファイルのほんの数だけがARG_MAX制限に達してはいけませんが、私のフォームで使用したファイルの数が多すぎる必要があります+(マンページを参照)。

答え2

2つの一般的な方法、つまりシェルワイルドカードがありますfind

  1. find-exec各結果に対して実行するアクションを指定するオプションがあります。各検索結果を使用可能にし、{}必要に応じて変更できます。パラメータ(たとえば)を提供しようとすると、echo foo > file状況はもう少し複雑になります。これを行うには、findにexecシェルを実行するように指示する必要があります。したがって、foo見つかったすべてのファイルをエコーするには、次のように実行できます。

    find /etc/ -name abc.txt -path "/etc/zyz*" \
        -exec bash -c "echo 'New line data' >> {}" \;
    
  2. シェルワイルドカード。一部のシェル(bash、zsh、ksh)は再帰ワイルドカードを処理できます。 Bashではshopt globstar。したがって、New line data各ファイルをエコーするには、次のようにします。

    shopt globstar
    for f in /etc/zyz*/**/abc.txt; do echo "New line data" >> "$f"; done
    

関連情報