シェルワイルドカードでゼロ個以上の演算子を一致させます。

シェルワイルドカードでゼロ個以上の演算子を一致させます。

*私はここで非常にマイナーな問題に固執しました:bashでシンボルを意味する方法0以上、ツールのようなsed

たとえば、名前ak*全体がaゼロ個以上のsでk構成されているファイルはすべて一致する必要があります。拡張子には、およびが含まれますaが、ak含まれakkませakkkakc

私はこれをunsetopt sh_globzshとset -o noglobbashで試しましたが、予想される動作を生成しません。

答え1

とは別にksh93、一般的に使用されるシェルには、ファイルの一致に使用できるsed、awkなどと同じ構文を持つ正規表現はありません。

Ksh93、bash、zshは構文が異なる正規表現を持ち、globと逆互換です。

  • ?単一文字と一致します(.通常の正規表現構文と同じ)。
  • […]ほぼ同じ方法で文字セットを一致させます。
  • *(FOO)ランダムな発生数の一致FOO(通常の正規表現構文と同じ)(FOO)*
  • また、1つ以上の項目と一致し、ゼロまたは1つの項目と一致します。+(FOO)?(FOO)
  • @(FOO|BAR)一致FOOするBAR
  • 部分文字列ではなく文字列全体に対して一致が機能します。部分文字列が必要な場合は、*開始と終了に入れてください。

shopt -s extglobこの構文を使用するには、bashとzshで有効にする必要がありますsetopt ksh_glob。だからbashでは、次のように書きます。

shopt -s extglob
ls a*(k)

また、見ることができます私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?

=~Ksh93、zsh、bashは、拡張正規表現(デフォルトではawk構文)を含む生成された演算子を使用して、文字列の正規表現一致を実行できます[[ … ]]。これはファイルのリストを表示するのに不便ですが、本当に必要に応じて行うことができます。

shopt -s dotglob  # <<< include dot files, for bash
setopt globdots   # <<< include dot files, for zsh
FIGNORE='@(.|..)' # <<< include dot files, for ksh
for x in *; do
  if [[ $x =~ ^ak*$ ]]; then
  fi
done

答え2

ls ak{k,}akで始まるファイルが表示され、その後に他のファイルが表示されるか、kファイルは表示されません。

$ touch ak akk akc
$ ls -l ak{k,}
-rw-rw-r-- 1 cas cas 0 Oct 27 10:30 ak
-rw-rw-r-- 1 cas cas 0 Oct 27 10:30 akk

globは正規表現ではありませんが、単純な*and以上の機能を果たします?

正規表現を使用して一致するファイル名を見つけるには、次のfindコマンドを使用できます。

$ find . -maxdepth 1 -type f -regex './ak+$' 
./ak
./akk

この-maxdepth 1オプションは、検索を現在のディレクトリにのみ制限します(サブディレクトリは検索されません)。

大文字と小文字を区別せずに検索するには、-iregex代わりにを使用してください-regex

find他のコマンドで見つかったファイルを使用する方法はいくつかあります。たとえば、

find . -maxdepth 1 -type f -regex './ak+$' -ls
find . -maxdepth 1 -type f -regex './ak+$' -exec ls -ld {} +
find . -maxdepth 1 -type f -regex './ak+$' -print0 | xargs -0r ls -ld
ls -ld $(find . -maxdepth 1 -type f -regex './ak+$')

最後の例は、1.ファイル名などのスペースを処理しない、2.コマンドラインの長さの制限など、さまざまなエラーモードに脆弱です。お勧めできません。

答え3

使用できる構文はbash次のとおりです。 ls a+(k) これは有効なシェルオプションによって異なりますbash shoptextglobUbuntu 14.04 GNU / Linuxでは、これはデフォルトで有効になっているようです。

仕組みは次のとおりです。

$ shopt extglob
extglob         on
$ ls
ak  akc  akd  akk  akkk  akkkk
$ ls a+(k)
ak  akk  akkk  akkkk
$ shopt -u extglob
$ shopt extglob
extglob         off
$ ls a+(k)
bash: syntax error near unexpected token `('
$

Bashのマニュアルから:

+(モードリスト)

与えられたパターンと1つ以上一致します。

パターンリストは、「|」で区切られた1つ以上のパターンのリストです。

Bashのマニュアルを参照してください。https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching

答え4

シェルによるいくつかのオプション:

$ touch a akk aka
$ ksh -c 'echo a*(k)'
a akk
$ zsh -o kshglob -o nobareglobqual -c 'echo a*(k)'
a akk

nobareglobqualここでは末尾はグローバル(k)修飾子とは見なされません)

$ bash -O extglob -c 'echo a*(k)'
a akk

$ zsh -o extendedglob -c 'echo ak#'
a akk

zsh#正規表現と同じです*

ksh93また、対応するglobでさまざまな種類の正規表現を使用できます。

$ ksh93 -c 'echo ~(E:ak*)' # extended RE
a akk
$ ksh93 -c 'echo ~(P:ak*)' # perl-like RE
a akk
$ ksh93 -c 'echo ~(X:ak*)' # AT&T augmented RE
a akk
$ ksh93 -c 'echo @(~(E)ak*)' # alternative syntax
a akk

関連情報