以下にサンプルテキストファイル(test_long_sentence.txt)があり、不要なデータを除いてtest1を含むすべての行をgrepしたいと思います。
見積もりが完了する前にどのようにデータを収集できますか?
test_long_sentence.txt
This is some unwanted data blah blah blah
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
This is some unwanted data blah blah blah
20 /test1/theme="Halloween"
注文する:
grep "test1" test_long_sentence.txt
実際の出力:
20 /test1/catergory="food"
20 /test1/target="Adults, \"Goblins\", Elderly,
20 /test1/type="Western"
20 /test1/theme="Halloween"
予想出力:
20 /test1/catergory="food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
20 /test1/theme="Halloween"
PS:私はtest_long_sentence.txtの編集を制御できません。だから私に一行で編集するように頼まないでください。
ベストアンサー1
awkを使う
$ awk '/test1/{line=$0; while (!(line ~ /[^\\]".*[^\\]"/)) {getline; line=line "\n" $0}; print line}' sentence.txt
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
20 /test1/theme="Halloween"
/test1/
条件です。現在の行に regex と一致する内容が含まれている場合、中かっこで囲まれたtest1
コマンドが実行されます。これらのコマンドは次のとおりです。
line=$0
現在の行の内容は「line」変数に格納されます。
while (!(line ~ !/[^\\]".*[^\\]"/)) {getline; line=line "\n" $0}
現在のコンテンツに
line
エスケープされていない2つの引用符が含まれていない場合は、次の行を取得してviagetline
に追加します。line
line=line "\n" $0
print line
変数には、
line
エスケープされていない2つの引用符が含まれており、それを印刷します。
コマンドを複数行にわたって分散したい場合は、上記と同じコマンドを次のように作成できます。
awk '
/test1/{
line=$0
while (!(line ~ /[^\\]".*[^\\]"/)) {
getline
line=line "\n" $0
}
print line
}' sentence.txt
sedを使う
$ sed -n '/test1/{:a; /[^\\]".*[^\\]"/{p;b}; N; ba}' sentence.txt
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
20 /test1/theme="Halloween"
仕組み:
-n
これは、明示的に要求されない限り、sedが何も印刷しないように指示します。
/test1/{...}
埋め込み行に対して、
test1
次のように中括弧で囲まれたコマンドを実行します。:a
これはラベルを定義します
a
。/[^\\]".*[^\\]"/{p;b}
パターンスペースに現在エスケープされていない2つの引用符が含まれている場合は、パターンスペースを印刷して残りの
p
コマンドをスキップしてb
次の行から始めます。N
ここに到達すると、現在エスケープされていない引用符が2つないことを意味します。パターン空間として次の行を読み込みます。
ba
ラベルに戻り、
a
そのラベルの後にコマンドを繰り返します。