シェルスクリプトの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
行の一致部分のみを返し、-P
Perl 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 |
K Lookbehindアサーションを使用して、より短い代替方法で一致開始(ept)をリセットします。周りを見てくださいそして正規表現でKをサポート |
( |
\ 1(1回以上(最大一致))にグループ化してキャプチャ: |
\w+ |
単語文字(az、AZ、0-9、_)(1回以上(最大限一致)) |
[/\.] |
すべての文字: "/", "." |
)+ |
\ 1の終わり(注:このキャプチャに数量子を使用しているため、キャプチャパターンの最後の繰り返しのみが\ 1に保存されます。) |
\w+ |
単語文字(az、AZ、0-9、_)(1回以上(最大限一致)) |