我正在尝试为一个应用程序制作一个日志文件摘要工具,该工具创建大量重复条目,只有不同的后缀来指示执行点。
下面是一个通用版本:包含这些内容的text_file(infile_grocery.txt
)。
milk skim fruit apple banana
milk skim fruit orange
milk skim fruit mango
milk skim fruit pomegranate
milk 2 percent fruit cherry tomato
milk 2 percent fruit peach
milk whole fruit pineapple
milk skim fruit strawberry raspberry
milk skim fruit strawberry rhubarb
milk whole fruit pineapple
我希望得到的是:
milk skim fruit apple banana, orange, mango, pomegranate
milk 2 percent fruit cherry tomato, peach
milk whole fruit pineapple
milk skim fruit strawberry raspberry, strawberry rhubarb
milk whole fruit pineapple
我目前准备的命令行是:
sed -rn "{H;x;s|^(.+) fruit ([^n]+)n(.*)1 fruit (.+)$|1 fruit 2, 4|;x}; ${x;s/^n//;p}" infile_grocery.txt
但我得到的结果是:
milk skim fruit apple banana, mango, strawberry raspberry
milk skim fruit strawberry rhubarb
milk whole fruit pineapple
我以某种方式丢弃了输入。 有没有更好的大师知道如何构建它?
这是一个
awk
的解决方案。
awk -F fruit '
$1==x{
printf ",%s", $2
next
}
{
x=$1
printf "n%s", $0
}
END {
print ""
}' input.txt
输出
milk skim fruit apple banana, orange, mango, pomegranate
milk 2 percent fruit cherry tomato, peach
milk whole fruit pineapple
milk skim fruit strawberry raspberry, strawberry rhubarb
milk whole fruit pineapple
这可能对你有用(GNU sed):
sed ':a;$!N;s/^((.*fruit).*)n2(.*)/1,3/;ta;P;D' file
解释:
-
:a
是循环的占位符 -
$!N
附加换行符,后跟下一行,最后一行除外。 -
s/^((.*fruit).*)n2(.*)/1,3/
将换行符之前的所有内容收集到反向引用 1(又名1
)中。在此收集从行首到将单词fruit
包含到反向引用 2(又名2
)的所有内容。将匹配2
之后的所有内容收集到反向引用 3(又名3
)中。将此正则表达式替换为反向引用 1,后跟逗号、空格,然后是反向引用 3。 -
ta
替换是否为真循环到占位符:a
-
P
替换是否是假打印,直到并包括模式空间中的第一个换行符。 -
D
如果替换为假,则删除模式空间中的第一个换行符并包括该换行符。
opref=""
nline=""
while read line; do
pref=`echo $line | sed 's/(.*fruit).*/1/'`
item=`echo $line | sed 's/.*fruits(.*)/1/'`
if [ "$opref" == "$pref" ]; then
nline="$nline, $item"
else
[ "$nline" != "" ] && echo $nline
nline=$line
fi
opref=$pref
done < input_file