我有一个要求,比如我必须删除文件中两个括号之间的字符串或数字。我使用了sed
命令,但它在一行上运行。我的左括号在一行,右括号在另一行。我该怎么做?
我尝试使用以下命令sed
:
sed -e 's/([^()]*)//g'
但这仅当我的左括号和右括号位于同一行时才有效。
例如:-
输入文件:
select a
,b
,c
FROM ABCD
(select e
,f
,g
,h FROM XYZ)
输出应该是:
select a
,b
,c
FROM ABCD
答案1
使用以下简单的 perl 脚本删除每对括号及其内容,甚至跨多行:
#!/usr/bin/perl
undef $/;
$text = <>;
#Flags: g=match repeatedly; s=dot matches newline
$text =~ s/\(.*?\)//gs;
print $text;
如果您想将其放入命令行中,请使用以下单行版本:
perl -p0777e 's/\(.*?\)//gs' [filename]
请注意,它比 perl 解决方案更短、更简单。-0777
禁用行分隔符(请参阅-0
下的标志man perlrun
),导致整个文件一步处理。好旧的 perl...它也(对于 perl 来说不寻常:-))比弄乱 sed 的模式空间更具可读性。
答案2
保留\n
ew 行(如果后续两行中有括号)
sed -e 's/\(^[^)]*) *\)\|([^)]*\() *\|$\)//g' filename
该脚本包含三种模式:
^[^)]*) *
从任何符号开始的行,除了)
直到)
之后space(s)
;([^)]*
来自(
任何符号,除了)
- 直到
)
与space(s)
之后;或者 - 直到
$
(行尾)
- 直到
对于多行情况:
sed ':1;s/([^)]*)//g;/(/{N;b1};' filename
答案3
使用 Gnu Sed。
-z
选项(空分隔记录),sed 将所有输入作为单个记录。请尝试:
sed -ze 's/([^()]*)//g'
答案4
对于 sed 的多行匹配,通常最简单的方法是读取整个文件,并对整个内容进行搜索/替换:
sed -n ' # disable auto-printing
1h # first line, move to hold space
1!H # not the first line, append to hold space
${ # at the end of file
x # move hold space to pattern space
s/([^)]*)//gp # perform search/replace and print
}
' file
还有更简单的(*)选项:
awk -v RS="" '{gsub(/\([^)]+\)/,"")} 1' file
perl -0777 -pe 's/\(.*?\)//sg' file
(*)“更简单”可能情人眼里出西施……