不要なデータを削除したいです。だから私の質問は、test1にtest1が含まれていない場合は、上記の行をどのように削除できるかです。または提案で終わりませんか?
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
**This is some unwanted data to remove**
20 /test1/type="Western"
20 /test1/end=category
**This is some unwanted data to remove**
20 /test1/Purpose=
20 /test1/my_purpose="To create
a fun-filled moment"
20 /test1/end=Purpose
予想出力:
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
20 /test1/end=category
20 /test1/Purpose=
20 /test1/my_purpose="To create
a fun-filled moment"
20 /test1/end=Purpose
次のいくつかのコマンドがあります。
1. grep -B1 'test1' test_long_sentence.txt
2. sed '/test1/!d' test_long_sentence.txt
3. sed '/\"$/!d' test_long_sentence.txt
いいえを組み合わせる方法がわかりません。 2と3(sedには正規表現とOR条件を含む複数のコマンドがあります)
答え1
lex
(またはflex
Linuxシステムの場合)は、スキャナー/レクサーの仕様を取得してそれをCプログラムに変換するプログラムです。スキャナ仕様は基本的にプログラム仕様と似ていますawk
が、awk
レコード指向バージョンlex
は「文字指向」です。
lex
次のソースと一緒に使用してくださいlexer.l
。
%x OUTPUT
%%
int quoted = 0;
^[0-9]*[ \t]*"/test1/" { BEGIN OUTPUT; ECHO; }
<OUTPUT>\n { if (!quoted) { BEGIN 0; } ECHO; }
<OUTPUT>[^\\]["] { quoted = !quoted; ECHO; }
<OUTPUT>. { ECHO; }
.|\n ;
スキャナはOUTPUT
ステータスを使用して現在の文字を出力するかどうかを追跡します。BEGIN OUTPUT
次の行が見つかったら、この状態に入ります。
<number> /test1/
(これは最初の規則によって処理されます。)行が終了し、現在引用されている文字列をスキャンしていない場合、この状態は終了します(これは2番目の規則によって処理されます)。
引用符付き文字列は、"
エスケープされていない文字で始まり、終了します(3番目の規則)。他のすべての文字はそのまま渡されるので、アクションは必要ありません(4番目の規則)。
状態でない場合はOUTPUT
すべてを無視します(最後の規則)。
これは、特定のデータ用に作成された一時スキャナです。エスケープされたバックスラッシュ()で終わる引用符付き文字列は処理されませんが、"some data \\"
表示されるデータには機能します。
ビルドしてください:
$ make lexer
lex -o lex.lexer.c lexer.l
cc -O2 -pipe -o lexer lex.lexer.c -ll
rm -f lex.lexer.c
(Linuxでは、使用するときにflex
使用する必要があるかもしれませんmake lexer LDLIBS=-ll
)
それを書く:
$ ./lexer <file
20 /test1/catergory="Food"
20 /test1/target="Adults, \"Goblins\", Elderly,
Babies, \"Witch\",
Faries"
20 /test1/type="Western"
20 /test1/end=category
20 /test1/Purpose=
20 /test1/my_purpose="To create
a fun-filled moment"
20 /test1/end=Purpose