删除带有图案的特殊字符的行

时间:2013-12-17 05:51:05

标签: linux shell unix awk

我正在尝试删除一行中没有前缀为\的特殊字符。 以下是特殊字符:

^$%.*+?!(){}[]|\

我需要在第二列中检查所有上面没有\前缀的特殊字符。 我正在尝试使用awk完成此操作,但没有运气。我想要输出如下。

input.txt中

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
5,sm\(oke
6,ra\in
7,pla\\y
8,wor\+k

output.txt的

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
6,ra\in

2 个答案:

答案 0 :(得分:2)

我相信你只是在寻找:

  awk '$2 !~ /\\[][|\\{}()!?+*.%$^]/' FS=,

这给出了给定输入文件的所需输出,但完全不符合问题中给出的描述。

修改

鉴于评论部分的讨论,似乎所需的解决方案应该输出包含特殊字符的所有行,除非该字符前面有反斜杠。鉴于该描述,我们必须从特殊字符列表中删除反斜杠。 A(非工作,为描述目的而给出)解决方案是:

awk '$2 ~ /[^\\][][|{}()!?+*.%$^]/' FS=,

这简单地匹配任何两个字符串,其中第一个不是反斜杠,第二个是字符][|{}()!?+*.%$^之一。这会失败,因为它不会捕获作为字符串的第一个元素出现特殊字符的情况。为此,我们扩展正则表达式,以便第一个字符可以是字符串的开头或任何不是反斜杠的字符。

awk '$2 ~ /(^|[^\\])[][|{}()!?+*.%$^]/' FS=,

我们需要重新排序特殊字符的原因是]在括号内具有特殊含义(即,它关闭括号!)并且必须首先列出以避免该含义。类似地,^必须,因为它是字符类的第一个成员(它否定了类)时具有特殊含义。 (其他角色并不重要;它们只是作为印刷事故重新订购。)

答案 1 :(得分:1)

诀窍的一部分是将特殊字符安全地放入角色类中,记住]^-(列表中没有)具有相关的特殊规则与他们在角色类。具体来说,^作为第一个字符否定了字符类(所以将它放在除第一个之外的某个地方),]字符终止字符类,除非它是{{1}之后的第一个或第二个字符。 }。

因此,你想要:

^

复杂(可怕)正则表达式匹配反斜杠后跟一个特殊字符;操作是awk '/\\[]^$%.*+?!(){}[\\|]/ { next } { print }' input.txt 以跳过该行。 next(也可以写成{ print }或任何其他真值)打印那些未被正则表达式消除的行。

示例输出

1

您可以优化处理以忽略第一个字段,依此类似于William Pursellanswer,它对列表中字符的重新排序与我的方式基本相同,但没有解释原因。

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
6,ra\in