私はここでかなり些細な問題に悩まされています:*
bash内の記号は、sed
などのツールと同様に、ゼロ以上を意味します。
例えば、 ak*
は、名前が完全にa
の後に0個以上のk
sが続くファイルと一致する必要があります。その拡張には、a
、ak
、akk
、およびakkk
が含まれますが、akc
は含まれません。
私はすでに試しましたunsetopt sh_glob
zshおよびset -o noglob
bashで;彼らは望ましい行動を生み出しませんでした。
_ksh93
_ を除き、通常のシェルには、sed、awkなどと同じ構文の正規表現がありません。これらは、ファイルの照合に使用できます。
Ksh93、bash、zshには、グロブと下位互換性のある異なる構文の正規表現があります。
?
_は任意の1文字に一致します(通常の正規表現構文の_.
_など)[…]
_は、ほとんど同じ方法で文字セットに一致します*(FOO)
は、任意の数の_FOO
_と一致します(通常の正規表現構文の_(FOO)*
_と同様)+(FOO)
は1回以上の出現に一致し、?(FOO)
は0回または1回の出現に一致します@(FOO|BAR)
は、_FOO
_または_BAR
_に一致します*
_を置きますこの構文は、bashでは_shopt -s extglob
_、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
_
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
グロブは正規表現ではありませんが、*
と?
だけではありません。
正規表現を使用して一致するファイル名を検索する場合は、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。コマンドラインの長さの制限など、さまざまな障害モードが発生しやすい傾向があります。推奨されません。
シェルに応じたいくつかのオプション:
$ 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
は、グロブでいくつかのタイプの正規表現を使用することもできます。
$ 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
bash
で使用できる構文は次のとおりです。ls a+(k)
これは、有効になっているbash
shopt
シェルオプションextglob
に依存します。 Ubuntu 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つ以上のパターンのリストです。
https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching のBashマニュアルでこれを参照してください。