Bashワイルドカードは、特定の拡張子を持つファイルを除くすべてのファイルと一致し、ドット文字を含むファイル名で機能します。

Bashワイルドカードは、特定の拡張子を持つファイルを除くすべてのファイルと一致し、ドット文字を含むファイル名で機能します。

私はオーディオファイルで作業しています。ほとんどはmp3ファイルですが、すべてではありません。 mp3以外のファイルや拡張子のないファイルに対していくつかのコマンドを実行したいと思います.mp3

私は正規表現には上手ですが、ファイルのグロービングにはあまり上手ではないと思います。

私はBashがこれを行うことができる「拡張ワイルドカード」を持っているという他のSO&SEの回答を見て学びました。

file ../foo/bar/*.!(mp3)

しかし、私のファイル名には、ファイル拡張子を構成する点に加えて点が含まれています。

../foo/bar/Naked_Scientists_Show_19.10.15.mp3
../foo/bar/YWCS_ep504-111519-pt1_5ej4_41cc9320.mp3_42827d48daefaa81ec09202e67fa8461_24419113.mp3
../foo/bar/eLife_Podcast_19.09.26.mp3
../foo/bar/gdn.sci.080428.bg.science_weekly.mp3

グローバルマッチは最後のポイントではなく、最初のポイントから始まるようです。ドキュメントを見てみましたが、正規表現ほど強力ではないようです。しかし、私は* nixシェルを扱うのに多くの時間を費やしていなかったので、すべてを実際に理解することはできませんでした。

Bashワイルドカードでこれを行う方法はありませんか?そうでない場合は、検索や他のツールを使用して同じ結果を得る方法を知ることはまだ価値があります。

答え1

*.!(mp3)foo.bar.mp3その後foo.には次のものがあるので一致しますbar.mp3いいえmp3

!(*.mp3)ここでで終わらないすべての項目と一致します.mp3

.名前に少なくとも1つ(隠しファイルで作成された先行ファイルを除く)が含まれているが終わらないファイルを一致させるには、.mp3次のようにします!(*.mp3|!(*.*))

とにかく、bash--enable-extended-glob-defaultshopt -s extglob

答え2

しかもGLOBIGNORE変数:

シェルGLOBIGNORE変数を使用して、パターンに一致するファイル名のセットを制限できます。GLOBIGNORE設定されている場合、GLOBIGNOREこれらのパターンのいずれかに一致する各一致ファイル名が一致リストから削除されます。このオプションを設定すると、大文字と小文字に関係なく、nocaseglobinのパターンに一致するものが検索されます。GLOBIGNORE設定されていて空でない場合、filename...は常に無視されます。GLOBIGNOREただし、GLOBIGNOREnull以外の値に設定すると、dotglobシェルオプションを有効にする効果があるため、 ''で始まる他のすべてのファイル名が.一致します。 「」で始まるファイル名を無視する以前の動作を取得するには、..*」を設定します。このオプションはGLOBIGNORE設定されていないとdotglob無効になります。GLOBIGNORE

$ touch a.b.mp3 .c.mp3 foo.tgz .bar
$ echo *
a.b.mp3 foo.tgz
$ shopt -s extglob; echo *.!(mp3)
a.b.mp3 foo.tgz
$ GLOBIGNORE='*.mp3'; echo *
.bar foo.tgz

答え3

私が考えることができる最も簡単な方法は次のとおりです。

find ${path-to-folder} -type f  | grep -vE ".*\.mp3$"

フォルダ内のすべてのファイルを見つけて、逆拡張grepにパイプすることができます。

特定の場所にあるすべてのファイルを探す

find ${path-to-folder} -type f 

grepを元に戻し、正規表現を使用して拡張子でフィルタリングする

grep -vE ".*\.mp3$"

Grepフラグ:

  • -vリバース grep

  • -Egrep 拡張 (正規表現を使用)

正規表現の説明:

  • .*0から可能なすべての文字までの文字数を示します。

  • \.実際のポイントを探す

  • mp3拡張を形成する文字列の場合

  • $生産中断を示します。

答え4

あなたの場合には適していないかもしれませんが、純粋な関数で関数を生成してから拡張子をパラメータBashとして渡す方法を知りたいです。bashrc未来には以下のように

したがって、基本的に私たちがすることは、必要な拡張を正規表現でチェックすることです。

for file in *; do
  if [[ $file =~ \.mp3$ ]]; then
    echo $file
  fi
done

関数として実装:現在のディレクトリから特定の拡張子を持つすべてのファイルを出力します。

getFileByExt(){
local extension="$1"
if (( $# == 1 )); then
for file in *; do
  if [[ $file =~ \.$extension$ ]]; then
    echo $file
  fi
done
else
  echo "Usage: ${FUNCNAME[0]} <extension>" 
## If run from bashrc, return the name of function
fi
}

拡張子が . であるすべてのファイルを取得するには、mp3次のように簡単です。

getFileByExt mp3

特定の拡張子のないファイルのインポート:特定の拡張子のない現在のディレクトリのすべてのファイルが出力されます。

getFileWithoutExt(){
local extension="$1"
if (( $# == 1 )); then
for file in *; do
  if [[ ! $file =~ \.$extension$ ]]; then
    echo $file
  fi
done
else
  echo "Usage: ${FUNCNAME[0]} <extension>"
fi
}

mp3同様に、拡張子なしでファイルを取得するには、次の手順を実行します。

getFileWithoutExt mp3

詳細は:

https://stackoverflow.com/questions/407184/how-to-check-the-extension-of-a-filename-in-a-bash-script

https://stackoverflow.com/questions/18278990/easiest-way-to-check-for-file-extension-in-bash/18280350

関連情報