该文件的内容为
some line DELETE_ME
some line this_is_the_pattern
如果 next 行中出现this_is_the_pattern
,则删除当前行中的最后一个字(在本例中为DELETE_ME
)。
如何使用sed或awk执行此操作?我的理解是sed比awk更适合这个任务,因为awk适合于对数据存储表格格式的操作。如果我的理解不正确,请告诉我。
答案 0 :(得分:2)
$ awk '/this_is_the_pattern/{sub(/[^[:space:]]+$/, "", last)} NR>1{print last} {last=$0} END{print last}' file
some line
some line this_is_the_pattern
此脚本使用名为last
的单个变量,该变量包含文件中的上一行。总之,如果当前行包含模式,则从last
中删除最后一个单词。否则,last
按原样打印。
详细说明,依次采取每个命令:
/this_is_the_pattern/{sub(/[^[:space:]]+$/, "", last)}
如果此行具有模式,请从最后一行中删除最后一个单词。
NR>1{print last}
对于第一行之后的每一行,打印最后一行。
last=$0
将当前行保存在变量last
。
END{print last}
打印文件的最后一行。
答案 1 :(得分:1)
awk 'NR>1 && /this_is_the_pattern/ {print t;}
NR>1 && !/this_is_the_pattern/ {print f;}
{f=$0;$NF="";t=$0}
END{print f}' input-file
请注意,这将修改删除最后一个字段的任何行中的空格,将空格挤压到一个空格中。
您可以将其简化为:
awk 'NR>1 { print( /this_is_the_pattern/? t:f)}
{f=$0;$NF="";t=$0}
END{print f}' input-file
您可以使用以下方法解决压缩的空白问题:
awk 'NR>1 { print( /this_is_the_pattern/? t:f)}
{f=$0;sub(" [^ ]*$","");t=$0}
END{print f}' input-file
答案 2 :(得分:1)
您可以使用tac
向后捕捉文件,以便首先看到模式。然后设置一个标志并删除您看到的下一行的最后一个单词。然后在最后,通过tac
将文件反转回原始订单。
tac file | awk '/this_is_the_pattern/{f=1;print;next} f==1{sub(/ [^ ]+$/, "");print;f=0}' | tac
答案 3 :(得分:1)
使用缓冲区将前一行保留在内存中
sed -n 'H;1h;1!{x;/\nPAGE/ s/[^ ]*\(\n\)/\1/;P;s/.*\n//;h;$p;}' YourFile
使用循环但相同的概念
sed -n ':cycle
N;/\nPAGE/ s/[^ ]*\(\n\)/\1/;P;s/.*\n//;$p;b cycle' YourFile
在这两种情况下,它都会删除前一行的最后一个单词,搜索模式也会连续2行
使用2个最后读取行,测试最后一个模式,如果存在则删除单词比打印第一行,删除它并循环
答案 4 :(得分:1)
惯用awk解决方案只是保留前一行的缓冲区(或一般情况下为N行),这样您就可以测试当前行,然后相应地修改和/或打印缓冲区:
$ awk '
NR>1 {
if (/this_is_the_pattern/) {
sub(/[^[:space:]]+$/,"",prev)
}
print prev
}
{ prev = $0 }
END { print prev }
' file
some line
some line this_is_the_pattern