シェルは部分パターンに一致する完全な単語を抽出します。

シェルは部分パターンに一致する完全な単語を抽出します。

シェルスクリプトの1行から単語を抽出する必要があります。同様の例を見たことがありますが、そのうち何も機能しませんでした。

例を見てください

word1 word2 word3/pattern/word4.word5 word6

両側にスペースをpattern返すべきではないことを考えると。word3/pattern/word4.word5

また、行が特定の文字で始まることを制限する必要があります#

行を分離するgrepコマンドが見つかりました。

grep "^[^#].*pattern" $FILE

で始まらずにを#含むすべての行を返しますpattern。それでは、この行からこの単語をどのように抽出できますか?

編集:Ubuntu 20.04を使う

また、この文に関連して、この例はそれがすべきものとある程度関連しています。このパターンは 1 行に 1 回だけ発生し、他の単語とスペースで区切られます。 1行が与えられたら、パターンを含む単語を返し、スペース(スペースを除く)に会うまですべてを左右に移動したいと思います。

答え1

パターンがスペースと一致しない限り、これをgrep -o '[^[:space:]]*pattern[^[:space:]]*'行う必要があります。 ([^[:space:]]*空白以外の文字と一致します。)

正規表現エンジンは通常、一番左の位置から始まり、一致を探し、一致は欲です。つまり、できるだけ多くの文字列と一致します。したがって、パターンの両側にスペース以外のすべてのスペースをここで選択する必要があります。

ハッシュ記号で始まる行を無視するには、パイプを使用してくださいgrep -v "^#"

たとえば、次のようなhello.txt場合

# my pattern
word1 word2 word3/pattern/word4.word5 word6

それから:

% < hello.txt grep -v "^#" | grep -o '[^[:space:]]*pattern[^[:space:]]*'
word3/pattern/word4.word5

答え2

別のGNUgrepアプローチ:

grep -oP '^[^#].*\K\S*pattern\S*" "$file"

この-oフラグはgrep行の一致部分のみを返し、-PPerl Compatible Regular Expressions(PCRE)を有効にして、-K「今まで一致したすべての項目を忘れます」。これにより、^[^#]#行の先頭にあるa以外のすべての文字と一致」を使用できますが、結果の先頭からすべての文字が除外されます。 PCRE は\S「空白なし」も提供します。

要約すると、これは#aで始まらず、埋め込まれた行とpattern一致し、そのパターンを含む空白ではなく最も長い文字列を印刷します。

同じ行に複数の項目がある場合、pattern前の.*項目と最も一致する項目が返されます\K。左端の一致を返すには、次を使用します。

grep -oP '^[^#].*?\K\S*pattern\S*' file

答え3

そして牛に似た一種の栄養 grep:

grep -oP '^(?<!#).*?\K(\w+[/\.])+\w+' file
word3/pattern/word4.word5

正規表現の一致は次のとおりです。

説明する
^ 文字列の始まり
(?<! 後ろを見て以下があることを確認してください。
# #
) 後ろ姿の終わり
.*? \nを除くすべての文字(0回以上(できるだけ少なく一致))
\K KLookbehindアサーションを使用して、より短い代替方法で一致開始(ept)をリセットします。周りを見てくださいそして正規表現でKをサポート
( \ 1(1回以上(最大一致))にグループ化してキャプチャ:
\w+ 単語文字(az、AZ、0-9、_)(1回以上(最大限一致))
[/\.] すべての文字: "/", "."
)+ \ 1の終わり(注:このキャプチャに数量子を使用しているため、キャプチャパターンの最後の繰り返しのみが\ 1に保存されます。)
\w+ 単語文字(az、AZ、0-9、_)(1回以上(最大限一致))

関連情報