![折叠连续行的一些重复部分](https://linux22.com/image/38791/%E6%8A%98%E5%8F%A0%E8%BF%9E%E7%BB%AD%E8%A1%8C%E7%9A%84%E4%B8%80%E4%BA%9B%E9%87%8D%E5%A4%8D%E9%83%A8%E5%88%86.png)
我在记事本中有这样的数据:
4480-1
4480-2
4480-3
4480-15
4581-1
4581-2
4581-3
4581-4
我们可以使用 for 循环之类的东西来做到这一点吗?用 sed 吗?
我所需的输出是4480-1&-2&-3&-15&4581-1&-2&-3&-4
答案1
这应该有效:
awk -F- '$1!=a{printf "%s", $1} {printf "-%s&", $2} {a=$1}' file | sed 's/&$/\n/g'
输出:
4480-1&-2&-3&-15&4581-1&-2&-3&-4
说明:
awk -F-
分隔符是-
$1!=a{printf "%s", $1}
4480
如果第一部分与最后处理的行不同,则打印第一部分{printf "-%s&", $2}
&
在最后打印第二部分{a=$1}
将 a 设置为已处理的行sed 's/&$/\n/g'
删除最后一个字符 a&
并添加换行符
答案2
我认为你不能sed
轻易做到这一点。使用以下方法更容易perl
:
$ perl -F'-' -anle '
$h{$F[0]} .= defined($h{$F[0]}) ? "&-".$F[1] : "-".$F[1];
END {
$,="&";
print @{[map { $_.$h{$_} } sort { $a <=> $b } keys %h]}
}
' file
4480-1&-2&-3&-15&4581-1&-2&-3&-4
答案3
sed 可能不可能。我正在用AWK做。我假设每行一个条目。
awk '
BEGIN { FS="-"; ORS=""; left="" }
{
if(NR>1){print "&"}
# Only print left part if it differs from previous line
if ($1!=left) {
print $1 "-" $2
left=$1;
} else {
print "-" $2
}
}' inputfile.txt
输出4480-1&-2&-3&-15&4581-1&-2&-3&-4
答案4
应该是 sed,但是这里是 perl:
#!/usr/bin/perl
while ( ($a,$b) = split /-/,<>) { $n->{$a}->{"-$b"}++;}
@_ = map { $_,
map { chomp; "$_&"; } reverse sort { $a <=> $b } keys $n->{$_};
} sort { $a <=> $b } keys $n;
@_[-1] =~ s/&$//;
print @_;
按数字排序的输出,不依赖于输入顺序:
4480-1&-2&-3&-15&4581-1&-2&-3&-4