長い話を短く(長すぎて終わりませんでした)

長い話を短く(長すぎて終わりませんでした)

.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オプション:指定された文字(この場合)のすべての出現は、パイプ(前の)の引数%に置き換えられます。|

上記の例では、次のことが発生します。

  1. echo「hello world」を標準出力(stdout)として印刷します。
  2. Pipe(|)はこの値(「hello world」)を次のコマンドに供給しますxargs
  3. xargsパラメータで区切り文字の発生を検索し、区切り文字を含むパラメータを分割します。
  4. xargsコマンドを実行する代わりに、新しく生成されたパラメーターを繰り返して、パラメーター値を使用します。%

追加読書

関連情報