オンラインでいくつかの答えを確認しましたが、コマンドにパラメータがあると機能しません-name
(おそらく私が何か間違っているかどうかはわかりません)。私が望むのは、ファイル名(ディレクトリ/パスではない)だけをリストすることです。より複雑にするには、ファイル名は同じですが拡張子が異なるため、およびを-name
使用して結果をフィルタリングする必要があります。-o
質問は私の提案です。または-printf
時にはbasename
正しく機能しないことがあります-name *.txt -o name *.pdf
。この問題を解決する他の方法はありますか?
私のファイルの例:
/dir1/dir2/dir3/dir4/
/file1.txt
/file1.pdf
/file1.ods ...etc.
リストごとにリストされている1つ以上の種類のファイルにのみ興味があります(-name
。
たった1つのコマンドで実行できますか?find
または、手順2で実行する必要があります(結果を一時ファイルに保存してから一時ファイルからディレクトリをフィルタリング/削除する)。私が達成したいことの結果は、各行にファイル名を持つテキストファイルです。
file1.txt
file1.pdf
file1.ods
file2.txt
file2.pdf
etc.
私が使用するコマンドは
find /dir1/dir2/dir3/dir4/ -type f -name '*.txt' -o -name '*.pdf' -o -name '*.ods' -printf "%f\n"
私はGNU Findを使用しています。
修正する
\(...\)
αГsнιιが私に思い出させてくれるようにを入れなければならないことが判明しました。
答え1
論理ORパターンで複数の式を使用する場合は、その-o
式をすべて囲む必要があります\( ... \)
。それ以外の場合、最後の式の結果は常に尊重され、-printf '%f\n'
すべての先行ディレクトリが削除されたファイル名のみを印刷するために使用されます。
find . -type f \( -name '*.pdf' -o -name '*.txt' \) -printf '%f\n'
バラよりman find
下にオペレーター次のセクションに関して( expr )
:
オペレーター
...(expr)
優先順位を強制します。括弧はシェルに特別なので、通常は引用符で囲む必要があります。
したがって\( ... \)
、または'(' ... ')'
(括弧の前と後の空白が重要です)を使用してエスケープできます。
答え2
-name
すでに述べたように、テストは括弧内にグループ化する必要があります。これらの括弧は、\( ... \)
たとえば'(' ... ')'
シェルから保護するためにエスケープまたは引用する必要があります(そうでない場合はサブシェルを指定します)。
標準を使用find
し、ファイル名のサフィックス処理を少し簡単にします。
set -- txt pdf ods
for suffix do
set -- "$@" -o -name "*.$suffix"
shift
done
shift
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename {} \;
まず、位置引数を表示するファイル名のサフィックスのリストに設定し(またはこれがスクリプトの場合はコマンドラインから取得します)、-name
テストのORリストを設定します。その後、コマンドラインで使用してくださいfind
。
その後、コマンドfind
自体はbasename
見つかった名前ごとにユーティリティを呼び出します。
あるいは、パラメータ置換を使用して、各パス名のファイル名部分を除くすべてを削除できます。ただし、これを行うには、パス名をインラインsh -c
スクリプトに渡す必要があります。
# [...] as before [...]
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec sh -c '
for pathname do
printf "%s\n" "${pathname##*/}"
done' sh {} +
basename
少なくとも処理するファイル名が多い場合は、使用されているバリアントよりも速く実行されると期待します。ただし、GNU用のcoreutilsを使用すると、次のようにbasename
使用できます。-a
--multiple
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename -a {} +
basename
これはできるだけ少ない回数で呼び出されます。ただし、coreutilsがインストールされている場合は、GNUを使用して同じ操作を実行するためにfind
使用できるfindutilsをインストールすることもできます。-printf '%f\n'