lsをgrepにパイプします。 grepがlsコマンドの出力を無視するのはなぜですか?

lsをgrepにパイプします。 grepがlsコマンドの出力を無視するのはなぜですか?

私はこのコマンドを使用して、ls -p | egrep "\<[A-Z]+\>"ディレクトリ名に/が追加されたすべての大文字ファイルとディレクトリ名を印刷しようとしています。ファイル/ディレクトリ名をすべて大文字でgrepするようにしましたが、私のコマンドが機能する理由を理解できませんでした。正しい出力が得られましたが、grepがXXX /などのディレクトリを一覧表示する方法を理解していません。

答え1

あなたの質問は、「大文字()以外の文字があっても拡張正規DIRNAME/表現と一致するのはなぜですか?」です。\<[A-Z]+\>/

あなたの正規表現は、以下を含むすべての項目と一致します。言葉すべて大文字:

$ printf '%s\n' "this is not matched" "this IS matched" | egrep "\<[A-Z]+\>"
this IS matched

幅が0の「単語の境界」、つまり「単語の文字」と、対応する型ではない文字(または行の先頭/末尾)の間のスペースと一致します\<\>単語文字はクラスのすべての文字[[:alpha:]_](文字と下線)です。

DIRNAME/あなたの表現は後に一致するものと一致します(DIRNAME前と後にD単語の境界がありますE)。


ディレクトリリストから特定の名前をフィルタリングするには、その他の行ベースのgrepテキスト操作ツールを使用しないでください。ファイル名に改行文字を含めることができるため、ファイル名に制限がない限り、行ベースのツールは正しい操作を実行するのが難しくなります。

代わりに、ディレクトリからすべての大文字の名前を取得するには、次の手順を実行しますbash

$ ls -p -d *
DIR/     FILE     TEST123  dir/     file     test123
$ ls -p -d !(*[[:lower:]]*)
DIR/     FILE     TEST123

これを行うには、shopt -s extglob拡張グロービングモードを有効にする必要があります。拡張ワイルドカードパターンは、小文字が!(*[[:lower:]]*)含まれていないすべての項目と一致します。

/このパターンは、ディレクトリ名に何が追加されるかは関係ありませんls -p。これは、パターンがファイル名と一致し、文字を含むファイル名がないためです/。また、スキーマが拡張されました。今後 ls呼び出されます。

数字を含む名前も消去するには、次のようにします。

$ ls -p -d !(*[[:lower:][:digit:]]*)
DIR/  FILE

(1つ以上の小文字または数字を含む名前は含まれていません。)または、

$ ls -p -d !(*[[:lower:]]*|*[[:digit:]]*)
DIR/  FILE

(ただし、小文字が1つ以上含まれる名前や数字が1つ以上含まれる名前は含まれません。)

答え2

文法は以下を\>意味します。単語の終わりに一致。あなたが望むものはおそらく

ls | egrep "^[A-Z.]+$"

ここでは^行の先頭と一致し、$行の終わりと一致します。

答え3

$  ls -p | egrep "[A-Z]+"
ABC
$  ls -p ???             
ABC  fif  out

私にとって行動を変えたのは単語の境界一致でした。

ls -p | egrep "\<[A-Z]+\>"私の場合、出力は提供されません。

比較ls -f |catしてls -p |cat。正規表現の修正を始めると、次のことがわかります。人々は気にしないでください。こんなこと:最終的には複雑すぎるので、これを行わないことをお勧めします。分析する体系的には、ls:ls出力はIEで動作するファイルのリストではなく、単純な「レポート」です。 (同じスクリーンショットMS Windowsのエクスプローラウィンドウとほぼ同じです。 )

$  ls -p |cat 
ABC
XYZ/

$  ls -f |cat 
XYZ
ABC

順序も異なりますが、/ディレクトリのフィルタリングにスラッシュを使用しないでください。

このようなものが必要でありfind . -type d(すべてのサブディレクトリにもディレクトリのみをリストします)、ファイルシステムを検索するための良い開始点があります。

$  find . -type d 
.
./XYZ
./d3
./d3/d2
./d3/d1
./d2
./d1

あなたの仕様は単純なls(おそらくgrepトリックを使用する)とクリーンなソリューションの間にありますfind。私はそれらのどれも提供しません。すべては、「生」ファイルシステム情報のリストに関するあなたの性格と将来の計画に依存します。

これは違いを示しています。

 $  find . -name "d1"
./d3/d1
./d1

$  ls -R |grep d1
d1
./d1:
d1
./d3/d1:

ls-grepを使用すると、「追加」行と文字を取得できます。必死にシェルでやり取りしてください。なぜできないのですか? (ファイル「d1」どこかに)

しかし、スクリプトで書かれたすべての内容は依存しなければならず、findそこには多くの可能性があります。ファイルシステムをデータベースに切り替えます。クエリとレポート:2つのステップ。lsコマンドラインのクイックオールインワンツールです。

$ ls -p -d !(*[[:lower:]]*|*[[:digit:]]*)

本当に深刻ですか?他にも戦略的なアドバイスはどうですか?コメントなどを参照してください。

ああ、そして誰もが想像できるすべてのライナーに参加したいかもしれません。だからバロック。私はいスタイル。


関連情報