我想删除不需要的数据。所以我的问题是,如果 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/
(这是由第一条规则处理的)。当一行结束并且我们当前没有扫描带引号的字符串时,我们退出此状态(这是由第二条规则处理的)。
带引号的字符串以未转义"
字符开始和结束(第三条规则)。所有其他字符均按原样传递,无需执行任何操作(第四条规则)。
当不在状态时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