我有一个如下数据集:
\"XXX \ START sapiodj \\" aj \d 2387 END hddo\" START bbcc \\" END ss
我的要求:我想删除START 和 END 之间所有出现的反斜杠\
和双引号。"
期望的输出:
\"XXX \ START sapiodj aj d 2387 END hddo\" START bbcc END ss
笔记:
- 同一行有多个 START/END
- 我只想删除START 和 END 之间的
\
and"
,而不是其他地方 - 我的文件有多行(类似于上面显示的行)
sed
我只需要使用
我尝试了如下所示的方法(试图"
先单独摆脱),但它没有给我想要的结果:
sed '/START/,/END/ s/"//g'
答案1
`
假设文件中没有字符。如果您只是将下面的行全部更改`
为任何其他字符,那么这些字符肯定不会出现在输入中。
sed -e 's/END/`/g;:X' -e 's/\(START[^`]*\)["\]/\1/g;tX' -e 's/`/END/g'
答案2
其实这并不难sed
。您始终可以使用\n
ewline分隔一个部分或者\n
您可以暂时将分隔符换成ewline。和你可以不用循环来做到这一点:
sed 's/$/START/;s/END/&
/g; y/D\n/\nD/
s/\([^D]*START\)*[D\"]*/\1/g
y/\n/D/;s/.....$//
' <<\IN
\"XXX \ START sapiodj \\" aj \d 2387 END hddo\" START bbcc \\" END ss
IN
有时你只需要以不同的方式思考问题即可。与其删除所有之间\\"
的内容START
,END
不如将问题转向如何保存\\"
仅当它们出现在行首和字符串以及行的最后一个和尾部之间时,START
它START
会变END
得更END
容易一些(如果,诚然,直觉上不是这样的话)。这是因为sed
处理*
零个或多个匹配的方式g
局部s///
替代语境。
虽然从头到第一个START
位会作为其余部分的自然结果而被清除,但最后END
到尾的位却不会 - 因此我们需要在行START
尾附加另一个位。获得额外的内容后,START
我们会\n
在每次出现 时附加一个 ewline 字符END
。然后使用y///
音译命令,我们同时将所有D
字符换成\n
ewlines,反之亦然。顺便说一句,音译命令y///
在这里不仅非常方便,而且比s///
替换命令更有效。
此时,l
我们的模式空间将打印:
\\"XXX \\ START sapiodj \\\\" aj \\d 2387 EN\nD hddo\\" START bbcc \\\\" EN\nD ssSTART$
正如您所看到的,现在所有\\"
需要保存的字符都正好位于行首或 aD
和字符串之间,并且它们之间START
没有s。D
因此,删除不需要的字符(包括我们额外的 s)的g
全局替换也替换了需要自行保存的字符。最后我们只需要再次交换和s 并删除最后一个。s///
D
\n
D
START
通过这种方式,您可以可靠地分隔字段sed
无论输入并且您不需要依赖任何不出现的字符,而是保证永远不会出现在一行上的字符 -\n
当然,这就是 ewline 字符。
完成后打印:
\"XXX \ START sapiodj aj d 2387 END hddo\" START bbcc END ss
答案3
和sed
:
sed 's/:/::/g;s/</:l/g;s/>/:g/g; # escape :, <, >
s/START/&</g; s/END/>&/g; # replace START/END with <>
:1
s/\(<[^>]*\)[\"]/\1/g;t1
s/[<>]//g;s/:g/>/g;s/:l/</g;s/::/:/g; # restore <>:'
和perl
:
perl -pe's|START.*?END|$&=~y/\\"//rd|ge'
答案4
你有在评论中指出这awk
也是允许的。所以我的回答就是基于此。
假设您的START
s 和END
s 是平衡的,如果您在任一单词上拆分行,您会发现您想要从所有偶数字段中删除反斜杠和双引号。为此:
awk -F 'START|END' '{
for(i=2;i<=NF;i+=2){ # For each even-numbered field
gsub(/["\\]/,"",$i) # Remove " and \ from it
$i="START"$i"END" # Put START and END back around it
}
}' your_file
这假设您的实现awk
具有gsub
我无法保证的功能。
作为旁注,您的sed
不起作用,因为它基本上是说“将替换应用于以行匹配开头START
并以行匹配结尾的行范围END
”。