想要使用sed在结果之间添加一个空行

时间:2016-03-22 16:02:43

标签: bash sed

想象一下,我有一个find语句,如下所示:

find . ! -path "*/test/*" -name *.txt -exec grep -Hin "Line" {} \;

生成

a.txt:4: Line 4
a.txt:6: Line 6
a.txt:8: Line 8
b.txt:3: Line 3
b.txt:5: Line 5
sub/c.txt:2: Line 2

我想格式化输出,以便每个文件后面都有空行。我的输出看起来像:

a.txt:4: Line 4
a.txt:6: Line 6
a.txt:8: Line 8

b.txt:3: Line 3
b.txt:5: Line 5

sub/c.txt:2: Line 2

我想通过sed管道结果来做到这一点(因为实际上我的find相当复杂,而且我已经用其他工具清理了结果。)

3 个答案:

答案 0 :(得分:2)

试试这个:

find..|whatever..| awk -F: 'NR>1&&$1!=p{print ""}{print;p=$1}'

答案 1 :(得分:2)

您可以附加另一个命令,例如生成空行的命令:

find . ! -path "*/test/*" -name *.txt -exec grep -Hin "Line" {} \; -exec echo \;

唯一的缺点是最后还会有一个额外的换行符。

对于sed解决方案,您可以管道

find ... | sed -r 'N;/^([^:]*):.*\n\1.*$/!{s/\n/\n\n/;P;s/.*\n\n/\n/};P;D'

详细说明:

N     # Append next line to pattern space

# If the lines up to the first colon don't match
/^([^:]*):.*\n\1.*$/! {
    s/\n/\n\n/      # Insert extra newline
    P               # Print first line
    s/.*\n\n/\n/    # Remove first line up to \n (like 'D' without starting cycle)
}
P     # Print first line of pattern space
D     # Delete first line of pattern space

BSD sed

要使用BSD sed进行此运行,-r必须替换为-E(或跳过,但必须转义括号)并且可能需要额外的分号才能使用闭幕式。

应该识别正则表达式中的换行符,但要将它们插入替换字符串中,必须使用'$'\n'''"$(printf '\n')"',因此命令变为

 sed -E 'N;/^([^:]*):.*\n\1.*$/!{s/\n/'$'\n'$'\n''/;P;s/.*\n\n/'$'\n''/;};P;D'

答案 2 :(得分:0)

只需用awk替换grep,例如:

find . ! -path "*/test/*" -name *.txt -exec \
awk -v OFS=':' 'tolower($0)~/line/{print FILENAME, NR, $0;f=1} END{if(f)print ""}' {} \;

并且您所做的任何其他清理都可以成为awk脚本的一部分,而不是拥有一堆不同的命令和管道或您当前正在使用的任何内容。