正規表現から一致を取得するだけです。
$ cat myfile.txt | SOMETHING_HERE "/(\w).+/"
出力は、括弧内で一致したもののみである必要があります。
grepは行全体と一致するため、使用できないと思います。
これを行う方法を教えてください。
2つのこと:
-o
_オプションが必要なので、(行全体ではなく)一致のみが出力されます。-P
_オプションを使用して、Perlの正規表現を使用します。これにはLookhead _(?= )
_およびLook behind _(?<= )
_、それらはパーツを探しますが、実際にはそれらを一致させて印刷しません。括弧の内側の部分だけを一致させたい場合:
_grep -oP '(?<=\/\()\w(?=\).+\/)' myfile.txt
_
ファイルに文字列/(a)5667/
が含まれている場合、grepは 'a'を出力します。
/(
_は_\/\(
_によって検出されますが、それらはlook-behind _(?<= )
_内にあるため、レポートされませんa
は_\w
_と一致し、したがって表示されます(_-o
_のため))5667/
_が見つかりますb <_\).+\/
_ですが、それらはlook-ahead _(?= )
_に含まれているため、レポートされません使用 -o
オプション(grep
)。
例えば:
$ echo "foobarbaz" | grep -o 'b[aeiou]r'
bar
sed -n "s/^.*\(captureThis\).*$/\1/p"
-n don't print lines
s substitute
^.* matches anything before the captureThis
\( \) capture everything between and assign it to \1
.*$ matches anything after the captureThis
\1 replace everything with captureThis
p print it
括弧内にあるものだけが必要な場合は、サブマッチのキャプチャをサポートするものが必要です(名前付きまたは番号付きのキャプチャグループ)。 Perlとsedではできますが、grepやegrepではできません。たとえば、Perlの場合:
Fooというファイルに次のような行がある場合:
/adsdds /
あなたがやる:
Perl -nle 'print $1 if /\/(\w).+\//' foo
文字aが返されます。それはあなたが望むものではないかもしれません。何を一致させようとしているのかを教えていただければ、より良い支援を受けることができます。 $ 1は、括弧の最初のセットでキャプチャされたものです。 $ 2は2番目のセットなどになります。
Shellに加えてbashとして質問にタグを付けたため、grepの横に別の解決策があります:
Bashには、Perlと同様に、=~
演算子を使用して、バージョン3.0以降に独自の正規表現エンジンがあります。
今、次のコードが与えられた:
#!/bin/bash
DATA="test <Lane>8</Lane>"
if [[ "$DATA" =~ \<Lane\>([[:digit:]]+)\<\/Lane\> ]]; then
echo $BASH_REMATCH
echo ${BASH_REMATCH[1]}
fi
bash
ではなくsh
として呼び出す必要があることに注意してください。$BASH_REMATCH
は、正規表現全体と一致する文字列全体を提供するため、<Lane>8</Lane>
${BASH_REMATCH[1]}
は、1番目のグループに一致する部分を提供するため、8
のみファイルに以下が含まれていると仮定します。
_$ cat file
Text-here>xyz</more text
_
また、_>
_と_</
_の間の文字が必要な場合は、次のいずれかを使用できます。
grepgrep -oP '.*\K(?<=>)\w+(?=<\/)' file
sedsed -nE 's:^.*>(\w+)</.*$:\1:p' file
awkawk '{print(gensub("^.*>(\\w+)</.*$","\\1","g"))}' file
PerlPerl -nle 'print $1 if />(\w+)<\//' file
すべて文字列「xyz」を出力します。
この行の数字をキャプチャしたい場合:
_$ cat file
Text-<here>1234</text>-ends
_
grepgrep -oP '.*\K(?<=>)[0-9]+(?=<\/)' file
sedsed -E 's:^.*>([0-9]+)</.*$:\1:' file
awkawk '{print(gensub(".*>([0-9]+)</.*","\\1","g"))}' file
PerlPerl -nle 'print $1 if />([0-9]+)<\//' file
これはあなたが要求していることを達成しますが、あなたが本当に望んでいることだとは思いません。正規表現の前に.*
を置いて、マッチの前に何でも食べますが、これは貪欲な操作であるため、これは文字列の最後から2番目の\w
文字にのみ一致します。
括弧と+
をエスケープする必要があることに注意してください。
sed 's/.*\(\w\).\+/\1/' myfile.txt