Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 重新编号列并替换文件中的行_Bash_Perl - Fatal编程技术网

Bash 重新编号列并替换文件中的行

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线,我想将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     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

请注意,这不会保留列之间的间距。

以下脚本将把输入文件的第三列更改为所需的数字,并且输出应按第三个字段排序

  • 脚本:torun.sh
  • filename=“input.txt”

    完成

  • 如何运行:./tunrun.sh | sort-k3

  • 请注意,awk将列的分隔符更改为单个空格。我不确定多个空格或制表符是否是您的分隔符。我们可以轻松地修复脚本,以便在确认后使用正确的分隔符正确显示行


  • 您已经将其标记为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