テキスト行で数字を探したいです。
cat log.txt | grep "License term"
01/01/2024:00:30 License term is 123 days.
私はこれから「マイナス」を分離したいと思います。キーワードマッチングの前後に単語をエコーする方法はありますか? ""is"の後に文字列を出力します"または""days"の前に文字列を出力します"のように?
おそらく同じように見えますが、今後は変わる可能性があります。 (ログエントリの書式やその他のテキストが追加されます)
答え1
次のコマンドは、正規表現に一致するすべての行、つまり部分文字列を含むすべての行、オプションの正の整数、行の末尾に部分文字列が続くすべての行を検索しますsed
。これらの行が見つかった場合は、行全体を整数に置き換え、変更された行を出力して、要求された番号を効果的に抽出します。log.txt
.*License term is \([0-9]*\) days\.$
License term is
days.
sed -n 's/.*License term is \([0-9]*\) days\.$/\1/p' log.txt
別の方法はを使用することですawk
。以下は、文字列を含む行のみを一致させてLicense term
から、その行から2番目のスペースで区切られた単語を出力する、やや異なるアプローチです。
awk '/License term/ { print $(NF-1) }' log.txt
明らかに、文字列を含む行からスペースで区切られた5番目のフィールドを削除するためにとgrep
組み合わせることもできます。cut
License term
grep -F 'License term' log.txt | cut -d ' ' -f 5
ここでは、正規表現の代わりに文字列を使用して検索していることを示すために、そのgrep
オプションを使用しています。-F
答え2
GNUでは、およびオプションをgrep
使用できます。これは、それぞれ「行内の一致部分のみを印刷」と「Perl互換正規表現を使用する」を意味します。 PCREの場合は、「これまで一致するものをすべて削除します」という意味で使用できます。これらすべてを組み合わせると、次のような結果が得られます。-o
-P
\K
$ grep -oP 'License term is \K\d+' log.txt
123
もちろん、これが一貫して動作するかどうかは、その中に何があるかによって異なりますが、log.txt
あなたの例では動作します。
答え3
pcre2grep
(または以前のバージョン)でpcregrep
:
pcre2grep -xo1 '\d\d/\d\d/\d\d\d\d:\d\d:\d\d License term is (\d+) days\.' < log.txt
行は保守的に一致し、実際にパターンに一致する行のみを選択し、そこx
から最初のo
キャプチャグループに一致する数が出力されます。1
p
またはPerl(in pcre2grep
)と同じです。
perl -lne '
print $1 if m{^\d\d/\d\d/\d\d\d\d:\d\d:\d\d License term is (\d+) days\.$}
' < log.txt
答え4
使用幸せ(以前のPerl_6)
~$ raku -ne '.put if s/ .* "License term is " (<[0..9]>*) " days." $/$0/;' log.txt
#OR:
~$ raku -ne '.put if s/ .* License \s term \s is \s (<[0..9]>*) \s days \. $/$0/;' log.txt
#OR:
~$ raku -ne '.put if s/ .* License <.ws> term <.ws> is <.ws> (<[0..9]>*) <.ws> days \. $/$0/;' log.txt
または:
~$ raku -ne 'if /License \s term/ { put .words[4] };' log.txt
#OR:
~$ raku -ne 'put .words[4] if /License \s term/;' log.txt
または:
~$ raku -e '$0.put for lines.match(/ "License term is " ( \d+ ) /);' log.txt
#OR:
~$ raku -e '.put for lines.match(/ "License term is " ( \d+ ) /);' log.txt
Rakuで書かれた答えは、すでに公開されている優れた答えと多くの点で似ていますsed
。awk
最初の2つの回答セットは、-ne
自動印刷されない限り、1行ずつフラグを使用します。最初のグループではs///
このフォームを使用してください。 2番目のグループでは、words
空白を分割するためにRakuのルーチンが使用されます。最後の回答セットでは、Rakuにlines
サブキーを検索または返すルーチンがありますmatch
。
入力例:
#dummy_line followed by blank line
01/01/2024:00:30 License term is 123 days.
#dummy_line
出力例:
123
Raku正規表現エンジンを使用すると、キャプチャタグとプレビュー/後ろ向きも使用できます。詳しくは、下記の最初のリンクをご覧ください。また、<[0..9]>
ASCII番号または\d
ASCII + Unicode番号をキャプチャすることもできます。