想象一下,我有一个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
相当复杂,而且我已经用其他工具清理了结果。)
答案 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脚本的一部分,而不是拥有一堆不同的命令和管道或您当前正在使用的任何内容。