タスクにfindを使用していますが、次のようなことをすると気付きました。
find `pwd` -name "file.ext" -exec echo $(dirname {}) \;
試合ごとにのみドットが表示されます。そのコマンドでdirname
をbasename
に置き換えると、完全なパス名が得られます。私はここで何かを台無しにしていますか、これは予想される動作ですか?私はbasename
にファイルの名前を与えるのに慣れています(この場合はfile.ext
)とdirname
は、パスの残りの部分を示します。
次のスクリプトについて考えてみます。
_#!/bin/sh
set -x
find `pwd` -name "file.ext" -exec echo $(dirname {}) \;
_
_set -x
_は、展開の仕組みと最終的なコマンドを示しています。実行すると、次の出力が表示されます。
_++ pwd
++ dirname '{}'
+ find /home/kibab -name file.ext -exec echo . ';'
_
したがって、最初に展開されるのはpwd
です。 2番目は$(dirname {})
です。これら2つのコマンドの結果は、findコマンドにドロップされます。したがって、findに_-exec echo .
_を指示しているので、期待される出力が表示されます。
basename
をdirname
に置き換えても、展開は行われますが、展開の結果は異なります。
pwd
は現在のパスに展開されます。上記の例では、結果は_/home/kibab
_です。basename {}
_が実行されます。このコマンドの結果は_{}
_です。上記の置換を行った状態でfindコマンドが実行されます。実行される最後のコマンドは次のようになります。
_find /home/kibab -name '*.png' -exec echo '{}' ';'
_
上記のコマンドを調べると、コマンドが見つかったファイルをエコーするだけであることがわかります。
おそらくあなたはこのようなものを望んでいますか?
_find `pwd` -name "file.ext" -printf "%f\n"
_
つまり問題は、$(...)または `...`が新しいシェルを開始してから置換を行うことです。
Bash -cの使用を検討してください:
$ find . -name '*.PNG' -exec bash -c 'git mv {} $(dirname {})/$(basename {} .PNG)48.png' \;
これにより、gitリポジトリのアイコンの名前がより標準的な形式に変更されます。
ここで{}は何かを実行する前に置き換えられるため、問題はなくなりました。
その例では、TMTOWTDIですが、本当に必要なことは何でも開始できるように、シンプルに保つようにしています。
見つかったファイルごとにdirname()を呼び出す必要はありません。 GNU findを使用すると、-printf
そしてそのより速いこの方法
find /path -type f -iname "*.ext" -printf "%h\n"
$(dirname {})
は、find
に渡される前にシェルによって評価されます。この評価の結果は_.
_なので、検出した各ファイルに対して_echo .
_を実行するようにfind
に指示するだけです。
_basename {}
_は_{}
_に評価されるため、$(basename {})
を$(dirname {})
に置き換えると、find
は各ファイルに対して_echo {}
_を実行します。これにより、各ファイルの完全な名前がエコーされます。
見つかったファイルごとにdirname
の結果を出力する場合は、echo
を省略できます。
_find `pwd` -name "file.ext" -exec dirname {} \;
_
コマンドが実際に実行される前にプロセス置換が評価されるので、ドットが表示されます。したがって、コマンドを別のシェルインスタンスに渡す必要があります。
回避策として、次の構文を使用します。
find $PWD -name "file.ext" -exec sh -c 'echo $(dirname {})' ';'
ただし、各ディレクトリで何かを印刷または実行する最も簡単な方法は、-execdir
によるものです。例:
find . -name "file.ext" -execdir pwd ';'
なぜそれが得られるのかわかりませんが、これを試してください:
find `pwd` -name file.ext |xargs -l1 dirname
これは、find
が検索するパスからの相対パスを出力するためです。 /
からこの検索を試みた場合、各パスに対して `` pwd\
を取得します。