我需要删除一个匹配的行和一个之前的行。 例如,在下面的文件中,我需要删除第1行和第1行。 2。
我尝试了“grep -v -B 1”页面。 of。“1.txt 我希望它不会打印匹配的行和上下文。
我尝试了How do I delete a matching line, the line above and the one below it, using sed?,但无法理解sed用法。
---1.txt--
**document 1** -> 1
**page 1 of 2** -> 2
testoing
testing
super crap blah
**document 1**
**page 2 of 2**
答案 0 :(得分:12)
你想做一些与answer given
非常相似的事情sed -n '
/page . of ./ { #when pattern matches
n #read the next line into the pattern space
x #exchange the pattern and hold space
d #skip the current contents of the pattern space (previous line)
}
x #for each line, exchange the pattern and hold space
1d #skip the first line
p #and print the contents of pattern space (previous line)
$ { #on the last line
x #exchange pattern and hold, pattern now contains last line read
p #and print that
}'
并作为单行
sed -n '/page . of ./{n;x;d;};x;1d;p;${x;p;}' 1.txt
答案 1 :(得分:2)
grep -v -B1
不起作用,因为它会跳过这些行,但稍后会包含它们(由于-B1
。要检查这一点,请尝试以下命令:
**document 1** -> 1
**page 1 of 2** -> 2
**document 1**
**page 2 of 2**
**page 3 of 2**
您会注意到会跳过page 2
行,因为该行不会匹配,而下一行就不会匹配。
有一个简单的awk解决方案:
awk '!/page.*of.*/ { if (m) print buf; buf=$0; m=1} /page.*of.*/ {m=0}' 1.txt
awk命令说明如下:
如果当前行具有“page ... of”,则表示您没有找到有效行。如果找不到该字符串,则打印上一行(存储在buf中)并将缓冲区重置为当前行(因此强制它滞后1)
答案 2 :(得分:1)
grep -vf <(grep -B1 "page.*of" file | sed '/^--$/d') file
答案 3 :(得分:0)
对sed不太熟悉,但这里有一个Perl表达式可以解决这个问题:
cat FILE | perl -e '@a = <STDIN>;
for( $i=0 ; $i <= $#a ; $i++ ) {
if($i > 0 && $a[$i] =~ /xxxx/) {
$a[$i] = "";
$a[$i-1] = "";
}
} print @a;'
编辑:
其中“xxxx”是您要匹配的内容。
答案 4 :(得分:0)
谢谢,我正在尝试使用 Foo Bah 给出的 awk 命令 删除匹配行和前一行。我必须多次使用它,因此对于匹配部分,我使用了一个变量。给定的 awk 命令有效,但在使用变量时它不起作用(即它不会删除匹配的 & 上一行)。我试过了:
awk -vvar="page.*of.*" '!/$var/ { if (m) print buf; buf=$0; m=1} /$var/ {m=0}' 1.txt