bashまたはzshで1つのファイル拡張子または別のファイル拡張子を繰り返します。

bashまたはzshで1つのファイル拡張子または別のファイル拡張子を繰り返します。

これは構文上正しいです。

for f in *bw;do echo $f;done

しかし、そのうちの1つを繰り返すには、どのように拡張機能を追加できますか?

  • 以下は機能しません:
    for f in *bw|*txt;do echo $f;done
    
  • これも機能しません。
    for f in *bw or *txt;do echo $f;done
    

答え1

知りません。あなたは再び繰り返す両方「拡張」し(必要な場合)、どちらか一方または両方が存在することを確認します。たとえば、1つだけを印刷する場合(最初の項目)、各ファイルのデフォルト名(拡張子なし)のリストを保持します。連想配列は参照しやすいので便利です。たとえば、Bashでは次のようになります。

declare -A files

for f in *.bw *.txt; do
  bn=${f%.*}
  if [ -z "${files[$bn]}" ] ; then
    echo "$f"
    files["$bn"]=1
  fi
done

答え2

大きな打撃を受けた状態でshopt -s extglobzshそしてKSH_GLOBできるようにする:

for f in *.@(bw|txt)

Bashに一致するものがない場合、ループは実行され、$fリテラル文字列に設定されます*.@(bw|txt)。これを防ぐには、bashで次の操作を行います。

shopt -s nullglob
for f in *.@(bw|txt)

zshでは、デフォルトで一致するものがない場合はエラーメッセージが表示されます。これを防ぐには、次を追加してください。N グローバル予選

for f in *.@(bw|txt)(N)

zshから、デフォルトのオプションを使用し、(N)一致するものがない場合は何もしないより簡単な解決策があります。

for f in *.(bw|txt)(N)

これはすべての項目をアルファベット順に並べ替え、2つの拡張子が混在するファイルです(つまり、拡張子のみが異なる重複名は(おそらく)連続的です)。パイプで区切られたパターン項目は、必要に応じて括弧内にリストでき、より多くのワイルドカードを含めることができます(例:)(zip|tar.?z)


1foo.bw foot.bw foot.txt foo.txtただし、ソートはロケールで順番に実行され、.今日の一般的なソートアルゴリズムではfirstは無視されます(likefootbまたはfoottbeforefootxとafter foobw)。

関連情報