我有一个如下文件。对于1ABC线,我想将1.line替换为3.line,将2.line替换为1.line,将3.line替换为4.line,将4.line替换为2.line。我想为2ABC线做同样的事情(在实际文件中我有1ABC,2ABC,3ABC ...... 1000ABC线)。更换线后,我应重新编号3.column。我该怎么做(我必须保留输出文件中列之间的间距)?
输入文件:
1ABC C1 1 0.349
1ABC H2 2 0.123
1ABC O1 3 0.217
1ABC H4 4 0.180
2ABC C1 5 2.015
2ABC H2 6 0.573
2ABC O1 7 1.929
2ABC H4 8 1.867
请求的输出:
1ABC H2 1 0.123
1ABC H4 2 0.180
1ABC C1 3 0.349
1ABC O1 4 0.217
2ABC H2 5 0.573
2ABC H4 6 1.867
2ABC C1 7 2.015
2ABC O1 8 1.929
答案 0 :(得分:1)
您已将其标记为perl,我还没有看到perl答案,所以我的方法就是这样:
看起来就像您正在做的是基于第二列的固定订单。那是对的吗?具体为H2,H4,C1,O1。
按第一列排序,然后排序,然后将第三列排序为 - 基本上 - 行号 - 您得到:
use strict;
use warnings;
my %results;
while (<DATA>) {
my ( $code, $OH, $index, $value ) = split;
$results{$code}{$OH} = $value;
}
my $rank = 1;
my @output_order = qw ( H2 H4 C1 O1 );
foreach my $code ( sort keys %results ) {
foreach my $OH (@output_order) {
print join( "\t", $code, $OH, $rank++, $results{$code}{$OH} ), "\n";
}
}
__DATA__
1ABC C1 1 0.349
1ABC H2 2 0.123
1ABC O1 3 0.217
1ABC H4 4 0.180
2ABC C1 5 2.015
2ABC H2 6 0.573
2ABC O1 7 1.929
2ABC H4 8 1.867
将打印:
1ABC H2 1 0.123
1ABC H4 2 0.180
1ABC C1 3 0.349
1ABC O1 4 0.217
2ABC H2 5 0.573
2ABC H4 6 1.867
2ABC C1 7 2.015
2ABC O1 8 1.929
答案 1 :(得分:0)
最直接的方法是只读取四行,然后按修改顺序将它们打印出来。
n=1
while read -r a1 b1 c1 d1 &&
read -r a2 b2 c2 d2 &&
read -r a3 b3 c3 d3 &&
read -r a4 b4 c4 d4
do
printf '%-8s %-5s %-3s %s\n' "$a2" "$b2" "$((n++))" "$d2"
printf '%-8s %-5s %-3s %s\n' "$a4" "$b4" "$((n++))" "$d4"
printf '%-8s %-5s %-3s %s\n' "$a1" "$b1" "$((n++))" "$d1"
printf '%-8s %-5s %-3s %s\n' "$a3" "$b3" "$((n++))" "$d3"
done
这会带来过多的重复性,通常是代码味道。更优雅的方法是将重新排序和重新编号分成不同的阶段。
reorder() {
while read -r l1 && read -r l2 && read -r l3 && read -r l4; do
printf '%s\n' "$l2" "$l4" "$l1" "$l3"
done
}
renumber() {
awk '{ $3 = ++n; print }'
}
reorder < in.txt | renumber > out.txt
请注意,这不会保留列之间的间距。