Bash 重新编号列并替换文件中的行
我有一个文件如下。对于1ABC线,我想将1.line替换为3.line,2.line替换为1.line,3.line替换为4.line,4.line替换为2.line。我想对2ABC行做同样的事情(在实际文件中,我有1ABC、2ABC、3ABC…1000ABC行)。在替换行之后,我应该对3.0列重新编号。我如何做到这一点(我必须在输出文件中保留列之间的间距) 输入文件:Bash 重新编号列并替换文件中的行,bash,perl,Bash,Perl,我有一个文件如下。对于1ABC线,我想将1.line替换为3.line,2.line替换为1.line,3.line替换为4.line,4.line替换为2.line。我想对2ABC行做同样的事情(在实际文件中,我有1ABC、2ABC、3ABC…1000ABC行)。在替换行之后,我应该对3.0列重新编号。我如何做到这一点(我必须在输出文件中保留列之间的间距) 输入文件: 1ABC C1 1 0.349 1ABC H2 2 0.123 1ABC
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
最直接的方法是只需读入四行,然后按修改后的顺序将它们打印出来
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
reorder(){
而read-r l1&&read-r l2&&read-r l3&&read-r l4;do
打印文件“%s\n”$l2“$l4”$l1“$l3”
完成
}
重新编号(){
awk'{$3=++n;print}'
}
重新排序out.txt
请注意,这不会保留列之间的间距。以下脚本将把输入文件的第三列更改为所需的数字,并且输出应按第三个字段排序
您已经将其标记为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
bash是您正在寻找的唯一选项吗?你研究过python或其他脚本语言吗?@vijayalakshmid没有。Bash不是唯一的选择。我刚刚编辑了“标签”。我对python不太了解。我也知道perl,但不太多。但是我不能用perl来完成它。它是有效的。谢谢我有一个小问题。您已多次使用此括号
{}
。这个括号在perl中是什么意思?我是一个新用户。我想学习。抱歉。如果您的意思是:$results{$code}
,那么这就是访问一个散列或关联数组,它是一组键值对,是将perl与其他语言区分开来的特性之一。有关更多详细信息,请参阅。
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