find . -type f -exec echo {} \;
上記のコマンドを使用して、先行する "./"文字なしでファイル名を取得したいと思います。基本的に次のようになりたいです。
filename
変える:
./filename
これを行う方法はありますか?
答え1
*
代わりに使用する.
と、行間隔が./
消えます。
find * -type f
シェルは最初に、それを*
現在の作業ディレクトリにある隠されていない(デフォルト)ファイルのソートされたリストに展開し、それを.
に渡しますfind
。これには次のような重要な意味があります。
- 隠しファイルは最上位レベルでは省略されますが、より深いレベルでは(検索されたファイルによって)省略
find
されます。 - リストは最上位レベル(通常はプラス記号)でソートされます。
- 現在の作業ディレクトリにファイルが多い場合は、コマンドに渡すことができる引数の数に制限がある可能性があります。
!
この方法は、名前という名前のファイルがある場合、または名前がで始まる場合は機能しません。名前のファイルがある場合は深刻な結果を招く可能性があります(
。)
-
-delete
答え2
別のファイル名を必要とせず、先行することなく完全な相対パスが必要であると仮定すると、./
GNUがある場合は次のようにfind
なります。
find . -type f -printf '%P\n'
find(1) のマニュアルページから:
%P
- ファイル名とそのファイルが見つかったソース名が削除されました。
それ以外の場合は、次のいずれかを試してください。
find . -type f -print | cut -d/ -f2-
find .[!.]* * -type f -print
最後のエントリは避けるべきです(ディレクトリにエントリが多い場合は、コマンドラインが長すぎることを考慮してください)。
-print
機能は同じです-exec echo {} \;
が、より良いです。外部プロセス呼び出しがないため、オーバーヘッドが低く、ダッシュで始まるファイル名による望ましくない副作用はありません。
答え3
find . -type f -exec echo {} \;
基本的な作業はfind
結果を印刷することです。明示的に指定しないと、デフォルトfind
で現在のディレクトリが検索されます。コマンドをに簡素化できますfind -type f
。
これはなぜ/いつ重要ですか?十分に大きいディレクトリでこのコマンドを実行した場合にのみパフォーマンスの違いが表示され始めます。ファイル名の印刷-exec echo {} \;
などの外部プロセスを開始する必要があるため、コンピュータはより不必要に動作します。/bin/echo
echo実行可能ファイルのインスタンスは、見つかった各ファイルに対して実行されますfind
。
削除に関する質問に答えるには、使用する方が./
効率的ですcut
。最初の2文字は常にです./
。cut -c3-
位置3以上の文字のみが保持されます。
> cd /etc/fonts/conf.d
> find -type f | cut -c3-
99pdftoopvp.conf
00kde.conf
65-khmer.conf
README
ファイル名に改行文字が含まれている場合、期待どおりに機能しませんが、これはまったく異なる話です。
答え4
引数でコマンドを実行したい場合の答えには要点はありませんprintf
。これは単なる例です。実際には、見つかったファイルを代わりに実行したい場合があります。-exec
echo
my-command
echo
非効率的で効果的な解決策は次のとおりです。
find . -type f -exec sh -c 'echo ${0#./}' "{}" \;
説明する:
sh -c 'echo $0' foobar
私たちは、印刷サブシェルが実行され、$0
次foobar
のように$0
渡されるという事実に依存します。foobar
- 代わりに、
$0
私たちは実際にそれを使用しています。${0#./}
$0
./
#./
パラメータ拡張 - exec(スラッシュ付きの
{}
ファイル名)から次に渡します。find
$0
sh -c
だから結局my-command
走らなければならない先行せずにファイルを見つけました。./
、あなたはします:
find . -type f -exec sh -c 'my-command ${0#./}' "{}" \;