首页 > 解决方案 > mac上如何使用sed删除部分行和下一行

问题描述

我有一个保存 ASCII 流输出的文件,所以它都是文本。我在 mac 上使用bash带有一系列sed语句的脚本来清理它。这有一个方面我很难过。

在文件中有一些地方我需要删除一行到末尾和下一行的一部分。

文件的示例部分:

abcdefg000

hijk

应该出来:

abcdefg
hijk

试过:

sed '/000/{N;d;}' FILE

那确实删除了下一个空白行,但也删除了第一行。我最终得到:

hijk

由于它是一个 mac,我不能使用 sed 插入换行符(我已经尝试过),但我已经成功地替换了一个字符并用于tr将其切换为换行符。想如果我这样做并且因为tr应该使用一个字符串,包括一个特殊字符,那么我应该能够删除两行 sed 并且这将起作用。

sed 's/000/|/' FILE | tr '|' '\n|' | sed '/|/{N;d;}'

但是,当我这样做时,我只得到换行符和 tr 切断管道。sed 然后找不到它,因此不会删除任何行。我得到:

abcdefg


hijk

man tr说它接受一个字符串,所以不知道为什么它不会\n |作为一个字符串。

我可以用其他语言脚本重做这个,但我现在已经花了足够长的时间,并且查看了足够多的其他问题和答案,我想让它工作。要么我遗漏了一些东西,sed要么tr有其他简单的方法可以做到这一点。

标签: bashsed

解决方案


awk应该可以很好地以您想要的方式修改文本文件。在以 结尾的行之后有条件地删除单个换行符000很简单。我们使用一个临时变量w来控制我们能够从中删除多少个“前面的行”。

awk '/000$/ { sub(/000$/,""); w = NR + 1; } 
     NF == 0 && w < NR { next; } 
     { print; }'

如果脚本需要处理000. 的解释d是我们是否处于我们正在删除空白行的状态。

awk '/000$/ {d=1;sub(/000$/,"");print;next;} 
     NF == 0 && d { next; } 
    { d = 0; print}'

您可以通过与另一个字符交换换行符然后换回来哄骗sed清理换行符。请注意,至少在 OS X 上,sed 无论如何都会在流中添加一个尾随换行符,因此您必须在流的最后摆脱流浪@|其他任何东西。

cat /tmp/data.txt | tr '\n@' '@\n' | sed 's/000@//' | \
    tr '\n@' '@\n' | sed '/^@$/d'

这是在000单个换行符之后压缩多个换行符的方法。或者一种方法。

cat /tmp/data.txt | tr '\n@' '@\n' | sed 's/000@*/@/' | \
    tr '\n@' '@\n' | sed '/^@$/d'

推荐阅读