次のファイルの4598行目を表示しようとしています。事実上、一致のn番目の出現後に行を表示したい。この場合、3回目の<Car>
の後の行です。これについてどうすればいいですか?
<Car>
10456
</Car>
<Car>
70192
</Car>
<Car>
4598
</Car>
awk -v n=3 '/<Car>/ && !--n {getline; print; exit}'
または:
awk '/<Car>/ && ++n == 3 {getline; print; exit}'
検索パターンを変数として渡すには:
var='<car>'
PATTERN="$var" awk -v n=3 '
$0 ~ ENVIRON["PATTERN"] && ++n == 3 {getline; print; exit}'
ここで、-v
の代わりにENVIRON
を使用すると、-v
はバックスラッシュエスケープシーケンスを展開し、バックスラッシュは正規表現でよく見られます(-v
で二重にする必要があります)。
GNU awk
4.2以降では、変数を strong typed regexps として割り当てることができます。 POSIXモードが有効になっていない限り(たとえば、$POSIXLY_CORRECT
環境変数を使用して)、次のことができます。
# GNU awk 4.2 or above only, when not in POSIX mode
gawk -v n=3 -v pattern="@/$var/" '
$0 ~ pattern && ++n == 3 {getline; print; exit}'
これがPerlのものです:
Perl -ne 'print && exit if $c==3; $c++ if /<Car>/;' file
GNU grep
を使用すると、次のようにその出力を解析することもできます。
grep -A 1 -m 3 '<Car>' file | tail -n 1
man grep
から:
-A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines.
Places a line containing a group separator (--) between
contiguous groups of matches.
-m NUM, --max-count=NUM
Stop reading a file after NUM matching lines.
GNU awk
できるよ:
gawk -v RS='</Car>' 'NR==3 && $0=$2' inputFile
sed
の別の方法を次に示します。
sed -n '/<Car>/{x;/.\{2\}/{x;$!{n;p};q};s/.*/&./;x}' infile
これは、カウントにホールドスペースを使用しています。<Car>
it e x
changesに一致する行に遭遇するたびに、ホールドバッファー内に文字が正確にN-1出現するかどうかを確認します。チェックが成功した場合、e x
changesが再度実行され、最後の行にない場合は、n
ext行を取得し、p
rintsパターンスペースを取得してから、q
uits 。それ以外の場合は、別の.
文字を保持スペースに追加し、e x
changesを戻します。
簡単なコマンドラインソリューションを次に示します。
grep -F -A1 '<Car>' filename | grep -E -v '<Car>|--' | tail -n +3 |head -n +1
tail
の後に+3の値を変更すると、任意のn番目の行を指定できます。