拡張子のないファイル名を検索するLinuxコマンド(拡張子が不明な場合)

拡張子のないファイル名を検索するLinuxコマンド(拡張子が不明な場合)

ファイル名を印刷するには次のコマンドを使用するのが好きですが、拡張子付きで印刷されます。

find . -type f -printf '%f\n'

私のディレクトリには、拡張子が異なるファイルがたくさんあります。--ignore='*.*'before と after の両方を追加してみました-printfが、うまくいきませんでした。例: myfile1.txt、myfile2.mp3 などのファイルがあります。myfile1、myfile2 などを印刷する必要があります。どうすればいいでしょうか?

答え1

もし私が正しく理解しているなら(知りませんでした。回答の2番目の部分をご覧ください) では、ドット文字を含むファイル名をリストしないようにする必要があります。

これは次のようになります:

find . -type f ! -name '*.*'

ファイル名グロビングパターンは、*.*少なくとも1つのドットを含むファイル名と一致します。前の部分は!一致の意味を否定し、最後まで到達するパス名は、名前にドットを含まないファイルのパス名になります。本当に古い!シェルの場合は、 asをエスケープする\!か、Unixのインストールを更新してください。単独で!は、bashの歴史拡張施設

GNU を使用して、見つかったパス名のファイル名コンポーネントのみを印刷するには、次のようにしますfind

find . -type f ! -name '*.*' -printf '%f\n'

標準find(またはGNU find)の場合:

find . -type f ! -name '*.*' -exec basename {} \;

ループ内のコマンド置換でこれを使用する前に、「find の出力をループするのはなぜ悪い習慣なのでしょうか?「」。


すべてのファイル名を一覧表示すると同時に、ファイル名の最後のドット以降のすべてを削除するには(「拡張子を削除」)、次のようにします。

find . -type f -exec sh -c '
    for pathname do
        pathname=$( basename "$pathname" )
        printf "%s\n" "${pathname%.*}"
    done' sh {} +

これにより、すべてのファイルの見つかったパス名がすべて短いシェル ループに送信されます。ループは各パス名を受け取り、basenameそれを呼び出してパス名のファイル名コンポーネントを抽出し、最後のドット以降のすべてを削除した結果の文字列を出力します。

パラメータ展開は、 「値の末尾から${pathname%.*}一致する最短の文字列(リテラル ドットの後に任意のテキストが続く)を削除する」ことを意味します。ファイル名の最後のドットの後のファイル名サフィックスを削除する効果があります。.*$pathname

の詳細についてはfind ... -exec ... {} +、例えば「`find` の -exec オプションを理解する「」。

答え2

Linuxではファイル拡張子というものは存在しません。.ファイル名のaには何の意味もありません(ただし.初めファイル名に . 文字が含まれている場合、そのファイルは隠しファイルとして識別されます。

findまた、私のシステムのマニュアル ページを確認しても--ignoreオプションは表示されません。

ただし、.名前に が含まれるファイルを無視したい場合は、 演算子を使用できfindます-not

find -type f -not -name '*.*' -print

答え3

他の人が指摘しているように、「拡張機能」は Unix システムにとって実際には何の意味もありません。しかし、簡単なコマンドでリストから拡張機能を削除することができますsed

例えば

find * -type f -print | sed 's/\.[^.]*$//'

ディレクトリがあり、それをリストに表示したくない場合は、

find * -type f -printf "%f\n" | sed 's/\.[^.]*$//'

単一のディレクトリの場合lsは、代わりにfind

ls | sed 's/\.[^.]*$//'

答え4

試す

find . -type f \! -name '*.*' -print

どこ

  • \!: なし (! はエスケープする必要があります)
  • name '*.*': 拡張子付きファイル名

関連情報