回答:
GNU では、そのfind
ための-printf
パラメーターを使用できます。例:
find /dir1 -type f -printf "%f\n"
-o
、暗黙より優先順位が低い-a
ため、-o
引数をグループ化したい場合が多いため)、理由はありません
検索に-printfオプションがない場合は、basenameを使用することもできます。
find ./dir1 -type f -exec basename {} \;
... {} ';'
-execdir
現在のファイルを自動的に保持するを使用します。{}
次に例を示します。
find . -type f -execdir echo '{}' ';'
$PWD
代わりに使用することもできます.
(一部のシステムでは、前面に余分なドットが生成されません)。
それでも余分なドットがある場合は、代わりに次のコマンドを実行できます。
find . -type f -execdir basename '{}' ';'
-execdir utility [argument ...] ;
-execdir
主は同じである-exec
ユーティリティがディレクトリから実行されることを除いて、主要な現在のファイルを保持しています。
の+
代わりに使用すると;
、{}
ユーティリティの呼び出しごとに可能な限り多くのパス名に置き換えられます。つまり、すべてのファイル名を1行で出力します。
./filename
代わりに私は得ていますfilename
。ニーズに応じて、問題ない場合があります。
$PWD
代わりにで試してください.
。
GNU findを使用している場合
find . -type f -printf "%f\n"
または、Ruby(1.9+)などのプログラミング言語を使用できます。
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
あなたがbash(少なくとも4)ソリューションを好むなら
shopt -s globstar
for file in **; do echo ${file##*/}; done
ファイル名のみに対して何らかのアクションを実行したい場合は、 basename
するのが難しいがあります。
例えばこれは:
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
basenameをエコーするだけ/my/found/path
です。ファイル名で実行したい場合は必要ありません。
しかし、その後xargs
、出力することができます。たとえば、別のディレクトリの名前に基づいてディレクトリ内のファイルを強制終了するには、次のようにします。
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
-exec
そして-execdir
遅いです、xargs
王様です。
$ alias f='time find /Applications -name "*.app" -type d -maxdepth 5'; \
f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l; \
f -print0 | xargs -0 basename | wc -l
139
0m01.17s real 0m00.20s user 0m00.93s system
139
0m01.16s real 0m00.20s user 0m00.92s system
139
0m01.05s real 0m00.17s user 0m00.85s system
139
0m00.93s real 0m00.17s user 0m00.85s system
139
0m00.88s real 0m00.12s user 0m00.75s system
xargs
の並列処理も役立ちます。
おかしなことに、私はxargs
なしの最後のケースを説明できません-n1
。正しい結果が得られ、最速です¯\_(ツ)_/¯
(basename
1つのパス引数のみを受け取りますがxargs
、それらをすべて送信します(実際には5000)-n1
。Linuxとopenbsdでは動作しません。macOSのみです...)
Linuxシステムのいくつかの大きな数値は、どのように-execdir
役立つかを確認するためのものですが、パラレルよりもはるかに低速ですxargs
。
$ alias f='time find /usr/ -maxdepth 5 -type d'
$ f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l
2358
3.63s real 0.10s user 0.41s system
2358
1.53s real 0.05s user 0.31s system
2358
1.30s real 0.03s user 0.21s system
2358
0.41s real 0.03s user 0.25s system
find
する-execdir
と、新しいプロセスの作成が比較的コストのかかる操作になるため、これが最も速くなります。
他の人が尖っアウトを持っているとして、あなたは組み合わせることができますfind
とbasename
が、デフォルトではbasename
(いずれかを使用して実行ファイルがパスごとに一度起動する必要がありますので、プログラムは、一度に一つのパス上でのみ動作しますfind ... -exec
かfind ... | xargs -n 1
潜在的に遅くなる可能性があります、)。
-a
onオプションを使用するbasename
と、1回の呼び出しで複数のファイル名を受け入れることができます。つまり、xargs
なし-n 1
でを使用して、パスをグループ化して、はるかに少ない数の呼び出しにまとめることができます。basename
化できます。これ、より効率的になります。
例:
find /dir1 -type f -print0 | xargs -0 basename -a
ここで私は含まれてきた-print0
とし-0
、ファイルとディレクトリの名前内の空白に対処するために(一緒に使用する必要が。
xargs basename -a
とのxargs -n1 basename
バージョン間のタイミングの比較を以下に示します。(like-with-likeの比較のために、ここで報告されるタイミングは最初のダミー実行の後であるため、ファイルメタデータがすでにI / Oキャッシュにコピーされた後で両方とも実行されます。)cksum
どちらの場合も、出力が使用する方法に依存しないことを示すためだけです。
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 basename -a | cksum'
2532163462 546663
real 0m0.063s
user 0m0.058s
sys 0m0.040s
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 -n 1 basename | cksum'
2532163462 546663
real 0m14.504s
user 0m12.474s
sys 0m3.109s
ご覧のように、basename
毎回起動することを回避する方がはるかに高速です。
basename
追加のコマンドライン引数を必要とせずに複数のファイル名を受け入れることがわかります。ここでの使用は-a
Linux上です。(basename --version
教えてくれbasename (GNU coreutils) 8.28
ます。)
私は最新のファイル名だけを与える解決策を見つけました(makandracardsページで):
ls -1tr * | tail -1
(ありがとうはArne Hartherzに行きます)
私はそれを使用しましたcp
:
cp $(ls -1tr * | tail -1) /tmp/