1. ホーム
  2. bash

[解決済み] ファイルの最初の行以降で正規表現にマッチする部分を取得する方法

2022-05-01 23:06:01

質問

約1000行のファイルを持っています。grepステートメントにマッチする行の後の部分が欲しいのです。

ということです。

cat file | grep 'TERMINATE'     # It is found on line 534

そこで、535行目から1000行目までのファイルをさらに処理したいのです。

どうすればいいのでしょうか?

どのように解決するのですか?

次のようにすると、一致する行が表示されます。 TERMINATE ファイルの終わりまで

sed -n -e '/TERMINATE/,$p'

説明しています。 -n のデフォルトの動作を無効にします。 sed は、そのスクリプトを実行した後、各行を表示します。 -e にスクリプトを表示しました。 sed , /TERMINATE/,$ は、アドレス(行)範囲の選択で TERMINATE 正規表現(grepなど)からファイルの末尾( $ ) と p は、現在の行を表示するprintコマンドです。

に一致する行の次の行から印刷します。 TERMINATE ファイルの終わりまで (マッチした行の後からEOFまで。マッチした行は含まず)

sed -e '1,/TERMINATE/d'

説明しています。 1,/TERMINATE/ はアドレス(行)範囲の選択で、入力の1行目から TERMINATE 正規表現、および d はdeleteコマンドで、現在の行を削除して次の行にスキップします。 として sed デフォルトの動作は、行を表示することです。 TERMINATE を入力の最後に追加します。

の前の行が必要な場合は TERMINATE :

sed -e '/TERMINATE/,$d'

また、前後の両方の行が必要な場合は TERMINATE を2つの異なるファイルで一度に実行します。

sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file

前後のファイルにはterminateの行が含まれるので、それぞれを処理するために

head -n -1 before
tail -n +2 after

sedスクリプトでファイル名をハードコードしたくない場合、可能です。

before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file

しかし、その場合は $ を展開しようとしないように、最後の行を意味します。 $w という変数があります(スクリプトをシングルクォートではなく、ダブルクォートで囲んでいることに注意してください)。

スクリプトのファイル名の後の改行が重要であることを伝えるのを忘れていたので、sedがファイル名の終わりを認識できるようにしました。

ハードコードされた TERMINATE を変数に変換してください。

一致するテキストを変数にして、前の例と同じようにするのです。

matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file

を使えば、前の例と同じようにマッチングテキストに変数を使用することができます。

## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"

## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"

## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"

このような場合のテキストを変数に置き換える重要なポイントは、以下の通りです。

  1. 変数( $variablename で囲まれている。 single quotes [ ' の中の変数は展開されません。 double quotes [ " となります。そこで、すべての single quotes から double quotes があり、変数に置き換えたいテキストが含まれている場合。
  2. sed の範囲も含まれます。 $ のように、すぐ後に文字が続きます。 $p , $d , $w . これらは展開される変数のようにも見えるので、これらをエスケープする必要があります。 $ の文字をバックスラッシュ [ \ ] のようになります。 \$p , \$d , \$w .