
メモ帳に次のようなデータがあります:
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}
&
最後に2番目の部分を印刷します{a=$1}
処理された行にaを設定するsed 's/&$/\n/g'
最後の文字を削除し&
、改行を追加します。
答え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 を使っています。1 行に 1 つのエントリを想定しています。
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