Linux 删除具有给定图案的特殊字符的行

Linux 删除具有给定图案的特殊字符的行,linux,shell,unix,sed,awk,Linux,Shell,Unix,Sed,Awk,我正在尝试获取带有特殊字符的行,这些字符的前缀不是\。以下是特殊字符: ^$%.*+?!(){}[]|\ 我需要检查以上所有特殊字符,这些字符在第2列中没有前缀\。我正试着用awk来完成这个,但是运气不好。我希望输出如下。 input.txt 1,ap^ple 2,o$range 3,bu+tter 4,gr(ape 5,sm\(ok\e 6,ra\in 7,p+la\\y 8,wor\+k output.txt 1,ap^ple 2,o$range 3,bu+tter 4,gr(ape 5

我正在尝试获取带有特殊字符的行,这些字符的前缀不是
\
。以下是特殊字符:

^$%.*+?!(){}[]|\
我需要检查以上所有特殊字符,这些字符在第2列中没有前缀
\
。我正试着用awk来完成这个,但是运气不好。我希望输出如下。

input.txt

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
5,sm\(ok\e
6,ra\in
7,p+la\\y
8,wor\+k
output.txt

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
5,sm\(ok\e
6,ra\in
7,p+la\\y

output.txt中有第7行和第5行,因为有两个特殊字符(一个带反斜杠,另一个不带反斜杠)

您可以尝试以下操作:

awk '
{
    line=$0
    sub(/\\[\^$%.*+?!(){}\[\]|\\]/,"")
    if(/[\^$%.*+?!(){}\[\]|\\]/)
        print line
}' input.txt

您可以尝试以下操作:

awk '
{
    line=$0
    sub(/\\[\^$%.*+?!(){}\[\]|\\]/,"")
    if(/[\^$%.*+?!(){}\[\]|\\]/)
        print line
}' input.txt
“最终”最终编辑:我想允许“\x”不管x是什么,但OP似乎不希望这样,所以我也修复了它

在试图找到一个“聪明”的regexp(它被“\\”或任何数量的“\”阻塞,但显然对其余部分有效…)

我在awk中重新编写了它,以“状态自动机”的方式进行:

这个想法:

如果处于“正常模式”,我们会遇到除“\”以外的特殊字符:我们打印这行! 如果处于“正常模式”,我们会遇到“\”?:我们进入“转义模式”,在该模式下,忽略下一个字符 (但如果我们没有下一个字符,我们也需要打印该行!)

剧本:

awk -F"," '
  {
    IN_ESCAPED_MODE=0 ;
    for (i=1 ; i<=length($2) ; i++)
     {  char=substr($2,i,1)

        if ( IN_ESCAPED_MODE == 0)
     {  if ( index(".^$%*+?!(){}[]|",char) > 0 )
             {  print $0 ; break ;
             }

            if ( index("\\" , char ) > 0 )
             {  IN_ESCAPED_MODE=1 ; continue ;
             }
         }

        if ( IN_ESCAPED_MODE == 1)
     {   if ( index(".^$%*+?!(){}[]|\\",char) > 0 )
           {  IN_ESCAPED_MODE=0 ; continue ;
               }
             else
               {  IN_ESCAPED_MODE=0 ; print $0; break;
               }
         }
     }

    if (IN_ESCAPED_MODE == 1)
     {
        print $0 ; break ;
     }

  }
'  input.txt > output.txt
它输出:

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
5,sm\(ok\e
6,ra\in
7,p+la\\y
10,\
12,\\\
13,.
15,..
16,^
18,$
20,%
22,*
24,+
26,?
28,!
30,(
32,)
34,{
36,}
38,[
40,]
42,|
(所以这一次似乎真的有效!)

如果您希望允许任何“\x”,而不仅仅是在“x”是特殊字符时:

更改“中间线”:

进入:

出于历史原因:regexp(在“大多数”情况下有效,但在某些情况下阻塞,例如,如果存在“\\”):

但是那一行不会显示第12行,例如

一本好书:。。。。和(可怕的…)

最终编辑:我想允许“\x”不管x是什么,但OP似乎不希望这样,所以我也修复了它

在试图找到一个“聪明”的regexp(它被“\\”或任何数量的“\”阻塞,但显然对其余部分有效…)

我在awk中重新编写了它,以“状态自动机”的方式进行:

这个想法:

如果处于“正常模式”,我们会遇到除“\”以外的特殊字符:我们打印这行! 如果处于“正常模式”,我们会遇到“\”?:我们进入“转义模式”,在该模式下,忽略下一个字符 (但如果我们没有下一个字符,我们也需要打印该行!)

剧本:

awk -F"," '
  {
    IN_ESCAPED_MODE=0 ;
    for (i=1 ; i<=length($2) ; i++)
     {  char=substr($2,i,1)

        if ( IN_ESCAPED_MODE == 0)
     {  if ( index(".^$%*+?!(){}[]|",char) > 0 )
             {  print $0 ; break ;
             }

            if ( index("\\" , char ) > 0 )
             {  IN_ESCAPED_MODE=1 ; continue ;
             }
         }

        if ( IN_ESCAPED_MODE == 1)
     {   if ( index(".^$%*+?!(){}[]|\\",char) > 0 )
           {  IN_ESCAPED_MODE=0 ; continue ;
               }
             else
               {  IN_ESCAPED_MODE=0 ; print $0; break;
               }
         }
     }

    if (IN_ESCAPED_MODE == 1)
     {
        print $0 ; break ;
     }

  }
'  input.txt > output.txt
它输出:

1,ap^ple
2,o$range
3,bu+tter
4,gr(ape
5,sm\(ok\e
6,ra\in
7,p+la\\y
10,\
12,\\\
13,.
15,..
16,^
18,$
20,%
22,*
24,+
26,?
28,!
30,(
32,)
34,{
36,}
38,[
40,]
42,|
(所以这一次似乎真的有效!)

如果您希望允许任何“\x”,而不仅仅是在“x”是特殊字符时:

更改“中间线”:

进入:

出于历史原因:regexp(在“大多数”情况下有效,但在某些情况下阻塞,例如,如果存在“\\”):

但是那一行不会显示第12行,例如

一本好书:。。。。和(可怕的…)

根据shell和sed的不同,可能会有不同的解释(尤其是
\
)。适用于我的AIX/KSH


根据shell和sed的不同,可能会有不同的解释(尤其是
\
)。在我的AIX/KSH上工作。sed输出与输入相同。txt仍然没有区别,我可以在输出中看到行
8,wor\+k
。txtah,是的,我没有考虑到:“\”后面有一个特殊字符!(因此,我的版本看到“\”并认为它是一个“\”,前面没有一个合适的“\”,所以它会打印出这行)。谢谢,接得好。我会设法解决的。我希望。。。(可能有一些特殊的情况,可能有一些奇怪的“\”)嗯,情况“d”是错误的。。。询问。我需要弄清楚如何在“[]”中包含“]”来修复它。sed输出与输入相同。txt仍然没有区别,我可以看到输出中的行
8,wor\+k
。txtah,是的,我没有考虑到:“\”后跟一个特殊字符!(因此,我的版本看到“\”并认为它是一个“\”,前面没有一个合适的“\”,所以它会打印出这行)。谢谢,接得好。我会设法解决的。我希望。。。(可能有一些特殊的情况,可能有一些奇怪的“\”)嗯,情况“d”是错误的。。。询问。我需要弄清楚如何在“[]”中包含“]”来修复它是否应该输出包含“\\\”的行?为什么?是否应该输出包含“\\\”的行?为什么?
 egrep '[^\][].^$%*+?!(){}[|]|[^\][\][^].^$%*+?!(){}[|\]'   input.txt > output.txt
sed '/[]\\^$%.*+?!(){}[|]/ {
  h
  s/\\[]\\^$%.*+?!(){}[|]/_/g
  /[]\\^$%.*+?!(){}[|]/ {
    x
    p
    }
  }' YourFile