そのため、ファイルシステムを調べて名前/etc
に大文字しかないファイルを一覧表示するかどうかを考えました。私は命令する
ls *[A-Z]*
ただし、コンソールにはサブ文字を含むファイルも表示されます。ただls
コマンドを使用したいです。コンソールプログラムロケールは関連していますか?
根本原因は何ですか?
答え1
[A-Z]
大文字を意味するわけではありません。A
から までの文字を表しZ
、これには小文字も含めることができます。通常はを使用する必要があります[[:upper:]]
。 (これはBashなしで動作しますextglob
。)
一致する文字は[A-Z]
ロケールによって異なります。
あなた明確にする完全に大文字で構成されたファイル名だけでなく、少なくとも大文字を含むすべてのファイル名をどこにでも表示したいが、使用すると、大文字を含まないls *[A-Z]*
一部のファイル名が表示されます。どの大文字。
これは、ロケールの事前編成順序に大文字と小文字(AaBbCcDd...など)が混在している場合に発生します。他のロケール(例LC_ALL=C
:)を設定できますが、一般的に最善の解決策は、大文字と特別に一致するパターンを作成することです。
どの文字が大文字かロケールによって異なる場合がありますが、そのロケールで大文字の場合はそれを含めることができます。だからこれは[[:upper:]]
デメリットというよりはメリットになるかもしれませんね。
代わりに使用してください[[:upper:]]
。
BashのようなほとんどのBourneスタイルのシェルは、globでPOSIX文字クラスをサポートしています。このコマンドは、/etc
名前に大文字が1つ以上含まれるエントリを一覧表示します。
ls -d /etc/*[[:upper:]]*
あなたが得るアイテムのいくつかはディレクトリかもしれません。ディレクトリだけをリストするのではなく、その内容を表示したい場合は、この-d
フラグを削除してください。で始まる項目がある--
場合は、パターンの前にフラグを付けることもできます。しかし、あなたはそれを知らないかもしれません。 (スクリプトでは通常、ここでこれを使用したいと思います。)/etc
-
--
ファイルをクリックしたくないかもしれませんが、クリックしたら...
で始まる項目は表示されません.
。通常、あなたはそれらにそれを見せたくありません。本当に必要な場合、ほとんどのシェルはそれに一致するglobを作成するか、デフォルトでそれを含めるようにglobbingを設定できます。.
Bashには前の項目を自動的に含めるオプションがあり、を使用して有効にすることdotglob
ができますshopt -s dotglob
。他のシェルについては参照
。あるいは、単に2番目のglobを作成することもできます。
ls -d /etc/*[[:upper:]]* /etc/.*[[:upper:]]*
最も広く使用されているBourneスタイルのシェルは中括弧の拡張をサポートしているので、繰り返しを減らし、より簡潔に書くことができます。
ls -d /etc/{,.}*[[:upper:]]*
Bashを含むほとんどのシェルで2つの別々のglobを作成すると、そのうちの1つが拡張されない場合はエラーメッセージが表示されます。なぜなら、ほとんどのシェルのデフォルト動作は拡張しないからです。ls
他の項目と一致する項目は引き続き表示されます。しかし、Stéphane Chazelasが指摘したように、非常に人気のあるZshを含む一部のシェルでは、コマンド全体が失敗してls
実行されません。コマンドを変更して再実行できるため、シェルを対話的に使用しても実際には有害ではありませんが、この構造は移植可能なスクリプトには適していません。 shellオプションを設定すると、Bashもこの方法で実行されますfailglob
。
このためにワイルドカードを拡張する必要はありません。
Bashでは、ワイルドカードモードでPOSIX文字クラスを使用するために拡張ワイルドカードを有効にする必要はありません。私のBash 4.3.48システムでは:
ek@Io:~$ shopt extglob
extglob off
ek@Io:~$ ls -d /etc/*[[:upper:]]*
/etc/ConsoleKit /etc/LatexMk /etc/ODBCDataSources /etc/UPower
/etc/ImageMagick-6 /etc/NetworkManager /etc/rcS.d /etc/X11
ただし、ファイル名と一致する必要があります。ただ大文字。
あなたは何ですかする以下を含むファイル名を一致させるには、ワイルドカードを拡張する必要があります。ただ大文字。その後、または+([[:upper:]])
を使用できます*([[:upper:]])
。これは拡張グローバル変数です。
Bashを使用している場合は、以下を参照してください。この記事、このガイド、3.5.8.1 パターンマッチング内部にGNU バッシュマニュアルもっと学ぶ。また、見ることができますStefan Chazerasの答え。
答え2
大文字のみで構成されるファイル名の場合。
(例:FOO
、、、ÉTÉ
;ΛΈΞΗ
とは異なりFOO.BAR
、ÉTÉ
(次にÉ
アクセントE
1と組み合わせたU + 0301))
そしてksh
またはzsh -o kshglob -o nobareglobqual
またはbash -O extglob
:
ls -d +([[:upper:]])
(代わりにzsh -o extendedglob
使用したいものkshglob
):
ls -d [[:upper:]]#
または、GNUを使用している場合ls
(ファイル名に有効な文字のみが含まれていると仮定):
ls --ignore='*[^[:upper:]]*'
またはfind
代わりに使用してください(ここでは引数だけを出力します。このような便利なオプションをls
使用したい)。-l
find . ! -name . -prune -name '*' ! -name '*[^[:upper:]]*'
(これは-name '*'
無効な文字を含むファイル名をフィルタリングするためのものであり、次の文字は! -name
フィルタリングできません(find
少なくとも一部の実装では))
小文字のないファイル名の場合
(しかし、のように文字以外の文字はまだ許可されていますABC.TXT
。)ここでksh
:
(FIGNORE='@(.|..|*[[:lower:]]*)'; ls -d -- *)
またはbash -O dotglob -O extglob
:zsh -o kshglob -o dotglob -o nobareglobqual
ls -d -- !(*[[:lower:]]*)
またはzsh -o extendedglob
:
ls -d -- ^*[[:lower:]]*(D)
または、GNUを使用している場合ls
(ファイル名に有効な文字のみが含まれていると仮定):
ls -A --ignore='*[[:lower:]]*' --ignore='.*[[:lower:]]*'
(--ignore='.*[[:lower:]]*'
事実何か追加が必要なのがジェゲンミスだと思います)
そしてfind
:
find . ! -name . -prune -name '*' ! -name '*[[:lower:]]*'
(一部のfind
実装では、有効な文字が小文字でなくても無効な文字を含むファイル名は含まれません。)
1つ以上の大文字を含むファイル名の場合:
(のように見えるFoo.bar
、).Été.txt
123.6
foo.bar
zsh -o dotglob
またはbash -O dotglob
(dotglob
名前で始まるファイルを含む)を使用します.
。
ls -d -- *[[:upper:]]*
そしてfind
:
find . ! -name . -prune -name '*[[:upper:]]*'
(一部のfind
実装では、一部の有効な文字が大文字であっても無効な文字を含むファイル名は含まれません。)
1文字の結合を可能にするには、zsh -o pcrematch
Unicode文字属性を利用してPerlに似た正規表現を使用できます。
ls -d -- *(e@'[[ $REPLY =~ "^(?>\p{Lu}\pM*)*$" ]]'@)
答え3
以前の回答を許してください。まだコーヒーを飲んでいません。
これを行うためにlsを使用できるかどうかはわかりません。ただし、この問題を解決するもう1つのgrepは次のとおりです。
LS | egrep ^[^a-z0-9]*$
答え4
なぜlsを使用したいのですか?代わりに find を使用できます。
find -regex './[A-Z]+'
編集:以下
に基づいていますman 7 glob
:
ワイルドカードマッチ
文字列に「?」、「*」、または「[」文字のいずれかが含まれている場合は、ワイルドカードパターンです。ワイルドカード割り当ては、ワイルドカードパターンをパターンと一致するパス名のリストに拡張する操作です。一致は次のように定義されます。ㅏ'? '(角括弧の間ではない)は、単一の文字と一致します.
'*' (角括弧の間ではない) は、空の文字列を含むすべての文字列と一致します。
キャラクタークラス
先行する「[」の後の最初の文字が「!」ではない「[...]」式は、単一の文字、つまり角括弧で囲まれたすべての文字と一致します。
一般的な表現
ワイルドカードパターンはやや似ていますが、正規表現ではありません。まず、テキストではなくファイル名と一致し、次にルールが異なります。たとえば、正規表現の「*」は、前のコンテンツのコピーが0個以上あることを意味します。正規表現には、否定が「^」で表される角括弧式があるため、POSIXではワイルドカードパターン「[^...]」の効果が定義されていないと宣言しました。
lsを使用するには、bashがfind -regexp
"*"をorと同じように翻訳しないことを覚えておく必要がありますgrep
。 * [AZ] *は、大文字の後に文字列が続くすべての文字列、つまりデフォルトですべての文字列を一致させようとします。