2016-06-28 14 views
0

egrepと正規表現を使用してファイルをパターン化してgrepしようとしています。私は必要なものGrep特定のアンダースコアパターンのファイル名

は例のための大会名を持つファイルを取得することです:コードはサイズに変えることができ姓とファーストネーム、市少なくとも3桁の数字を持っている必要があります

xx_code_lastname_firstname_city.doc 

私は以下のコードをしようとしていますが、それは私が望むものを達成するために失敗します。その後、beggining、少なくとも3単語を持っている任意のコードから標準xx_を取得しようとしている

ls -1 | grep -E "[xx_][A-Za-z]{3,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[.][doc|pdf]" 

それ以降は別のアンダースコアを持つ必要があります。 誰かが助けてくれますか?次のように

+0

'ls | grep' - http://mywiki.wooledge.org/ParsingLsを参照してください。 –

+0

使用しているシェルを指定できますか? Red Hatは複数のbashを出荷していますか? mksh? –

+2

ところで、 '[xx_]'は* 1文字にマッチする 'x'か' _'です。 –

答えて

5

は、extglobを考えてみましょう:

#!/bin/bash 
shopt -s extglob # turn on extended globbing syntax 

files=(xx_[[:alpha:]][[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])[email protected](doc|docx|pdf)) 

[[ -e ${files[0]} ]] || -L ${files[0]} ]] && printf '%s\n' "${files[@]}" 

... 3以上のアルファベット文字の任意の文字列と一致し

[[:alpha:]][[:alpha:]]+([[:alpha:]]) 

ので、これは動作します - 明示的に彼ら二人を、それらのうちの1つは、 +()の1つ以上のextglob構文を使用します。


同様に、

@(doc|docx|pdf) 

は...これらの3つの特定の文字列のいずれかに一致します。

+0

'nullglob'を使って、醜い' [[-e || -L]] 'トリックで、私がコメント': 'で示唆したことを得るでしょう。 –

+0

@gniourf_gniourf、私は 'nullglob'に少し注意します。私たちは、OPが直後にそれをオフに戻さないようにしなければなりません。引数が与えられていなければデフォルト動作を持つコマンドでトラップに入るのは簡単です。 off-by-defaultで始まります。 –

+0

そして 'failglob'を使います。しかし、いずれかを使用することを強く推奨します。 –

3

したがって、xx_と一致させようとしていますか?その部分であなたのパターンを始めてください。

xx_ 

次に、「3桁の数字」が表示されます。私はあなた自身の正規表現に基づいて、 "数字"によって文字を意味すると仮定しようとします(したがって、[a-zA-Z]文字クラス)。定量化を非貪欲なものにして、意図しない捕獲動作を避けましょう。

xx_[a-zA-Z]{3,}? 

ファーストネームとラストネームの部分については、少なくとも2文字以上の可変長を指定しています。これらの数量子が限定数の後ろに?文字を追加することによって、非貪欲であることを確認しましょう。あなたの正規表現によると、それはあなたの都市構造がfirstnameとlastnameビットと同様の形を取ると期待しているようにも見えます。 3つすべてを追加しましょう。

xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\. 

注:私たちはそれは我々が興味を持っているテキストのどこにも表示されるように期待していないリテラル"."、続いだと主張したので、私たちは、街の数量詞は、非貪欲にする必要はありませんでしたマッチングで正規表現の構文のメタ文字であるため、エスケープされていることに注意してください。

最後に、ファイル拡張子は、"docx"というようになります。私はまたあなたの正規表現に"doc""pdf"拡張子を置くことを参照してください。これら3つすべてを組み合わせましょう。

xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\.(docx?|pdf) 

これがうまくいきます。説明が必要な場合はコメントしてください。 "doc""docx"部分がどのように1つの要素に凝縮されているかに注目してください。これは必要ではありませんが、私はそれがこのフォームでもっと慎重に見えると思います。それは(doc|docx|pdf)と書くこともできます。私の味のために少し繰り返します。

+0

'\ w'は' grep -E'でサポートされておらず、POSIX ERE構文を使用し、PCRE拡張は使用しません。 (GNU grepのいくつかのバージョンでは、libpcreサポートでコンパイルされている場合は 'grep -P'がサポートされていますが、これはオプションのコンパイル時拡張です)。 –

+0

良いキャッチ。私は特定の文字クラスを使用します。私はいつもPCREを使います...私の正気を維持するのに役立ちます。 – wpcarro

+1

私は '[[:alpha:]]'を '[a-zA-Z]'に優先して使用したいと思います。もし 'C 'ロケールであれば違いはありませんが、世界の他の地域では、別のアルファベットで表示されます。 :) –

関連する問題