.txtというファイルを含むすべてのディレクトリでコマンド(makeコマンドと同様)を実行するスクリプトを作成したいと思いますmy_suites.cfg
。
答え1
find
指定されたファイルを含む作業ディレクトリ(pwdなど)を使用してコマンドを実行できます。
find /path/to/repository -type f -name my_suites.cfg -execdir pwd \;
/path/to/repository は相対パスでもあります ("." も可能)。
答え2
ラベルに示すように、bash
次のglobstar
オプションを使用できます。
shopt -s globstar
for d in **/; do if [[ -f "$d/my_suites.cfg" ]]; then cd "$d"; make; cd -; fi; done
これは、現在のディレクトリ内のすべてのディレクトリとサブディレクトリを繰り返し、ファイルがmy_suites.cfg
存在することを確認し、その場合はそのディレクトリを変更し、を呼び出して元のmake
ディレクトリに戻ります。
答え3
したがって、問題を要約すると、特定の名前を持つ各ファイルに対して一度に1つずつbashコマンドを実行しようとします。
最初からすべてを自分で書くのではなく、既存のツールを使用すると仮定すると、いくつかのアイデアがあります。
長い話を短く(長すぎて終わりませんでした)
最新のファイルがまだ認識されていないかどうかは問題ではありません。
$ mlocate --basename --regex "^my_suites.cfg$" \
| xargs dirname \
| xargs -d '\n' <command-to-run-on-the-file>
それ以外の場合、効率がそれほど重要ではない場合(~
ホームディレクトリでのみ再帰的に検索すると仮定):
$ find ~ -name "my_suites.cfg" -type f \
| xargs dirname \
| xargs -d '\n' <command-to-run-on-the-file>
フルバージョン
ファイルを探す
探しているファイルがシステム全体に分散している場合は、妥当性について心配する必要があります。
より速い方法
いくつかの欠点があります。
$ mlocate --basename --regex "^my_suites.cfg$"
mlocate
ほとんどのディストリビューションで毎日更新されるデータベースでファイルパスを見つけます。そのため、最近作成されたファイルや最近移動されたファイルを認識できない可能性があります。ただし、ファイルシステム自体を介さずにデータベースを調査するため、検索は非常に効率的です。- この
--basename
オプションは、パス/ディレクトリを除いて、探しているファイルの直接名を指定します。 - この
--regex
オプションを使用すると、検索パターンに正規表現を使用できます。 (^
文字列はそこから始まり、$
文字列はそこで終わると予想されます。)
「常に最新の状態」アプローチ
$ find / -name "my_suites.cfg" -type f
find
既定では、見つかったすべてのフォルダに移動し、my_suites.cfgという名前のすべてのファイルを一覧表示します。多くの読み取り操作を実行する必要があるため、検索するフォルダが多いほど速度が遅くなります。- この
-name
オプションはmy_suites.cfg名前私たちが探しているファイルを含むフォルダではなく、ファイルのディレクトリです。 - この
-type
オプションは、私たちが探しているものを指定します。文書、ディレクトリ、シンボリックリンク、ソケット、その他の項目には適用されません。
各ファイルに対してカスタムコマンドを実行する
...それがxargs
目的です。
簡単な例
$ echo "some simple example" | xargs mkdir
$ # now there are three directories, named by the echoed words
$ ls
example simple some
もっと複雑なもの:
$ echo "hello world" | xargs -d ' ' -I % echo 'Print a word: %'
Print a word: hello
Print a word: world
-d
オプション:引数を互いに区切る文字を指定します(ここでは空白)。-I
オプション:指定された文字(この場合)のすべての出現は、パイプ(前の)の引数%
に置き換えられます。|
上記の例では、次のことが発生します。
echo
「hello world」を標準出力(stdout
)として印刷します。- Pipe(
|
)はこの値(「hello world」)を次のコマンドに供給しますxargs
。 xargs
パラメータで区切り文字の発生を検索し、区切り文字を含むパラメータを分割します。xargs
コマンドを実行する代わりに、新しく生成されたパラメーターを繰り返して、パラメーター値を使用します。%
追加読書
- Unix xargs
- 正規表現:チュートリアル
- マンページを探す
- この答えも存在し続けますハスキーのウェブサイト(私の個人ホームページです)