从数据中声明变量,并在一行代码中对数据运行多个命令

时间:2016-02-01 07:27:30

标签: linux bash perl awk sed

我今天遇到了一个错误,希望其他人对我的解决方案有所了解。错误发生在数据集中。第一行/第二行/记录的最后一列/字段中的数据应该相同,行/记录1的倒数第二列/字段始终为“1”。问题是当时不是这样,并且需要采取措施来纠正它。

不正确的数据就是这样,在名为“sample.txt”的文件中:

5@Comedia   @5@3@2@3@1/2  @3@1.6  @1@2 1/2@11@14 1/4
3@Melanistic@3@4@2@4@1 1/2@4@2 3/4@3@5    @2 @4 3/4
2@Pure      @4@5@5@5@3 1/2@5@4 3/4@5@8    @3 @6 1/2
4@Profit    @2@2@1@2@1.6  @1@1.6  @2@2 1/2@4 @6 1/2
1@Whammy    @1@1@1@1@1.6  @2@1.6  @4@5 1/2@5 @8 1/4

正确的数据应如下所示:

 5@Comedia   @5@3@2@3@1/2  @3@1.6  @1@2 1/2 @1@4 3/4
 3@Melanistic@3@4@2@4@1 1/2@4@2 3/4@3@5     @2@4 3/4
 2@Pure      @4@5@5@5@3 1/2@5@4 3/4@5@8     @3@6 1/2
 4@Profit    @2@2@1@2@1.6  @1@1.6  @2@2 1/2 @4@6 1/2
 1@Whammy    @1@1@1@1@1.6  @2@1.6  @4@5 1/2 @5@8 1/4

我目前的解决方案是一个多步骤的过程,我有一种感觉可以简化。任何建议都非常感谢。

1)创建一个bash变量:

 length=$(cat sample.txt |awk -F@ 'NR==2{print $NF}') 

2)在第1行创建一个包含正确信息的文件:

awk -F@ -v l="$length" 'NR==1{$(NF-1)=1;$NF=l;print $0}' OFS=@ sample.txt >sample1.txt

3)将剩余信息附加到创建的正确行文件

awk -F@ 'NR>1{print $0}' sample.txt >>sample1.txt   

是否有一个可以完成上述三个步骤的awk,sed或Perl衬管(或管道组合)?

3 个答案:

答案 0 :(得分:1)

如果我理解正确,那么此程序将按您的意愿执行

它从文件中读取前两行,并用1替换第一行的最后两个字段,并从第二行替换最后一个字段。然后它打印这两行并复制文件的其余部分

输入文件的路径应该是命令行上的参数

use strict;
use warnings 'all';

my $line1 = <>;
my $line2 = <>;
my ($val) = $line2 =~ /.+\@(.+)/;

$line1 =~ s/\@[^\@]*\@[^\@]*$/\@1 \@$val\n/;

print $line1;
print $line2;

print while <>;

输出

5@Comedia   @5@3@2@3@1/2  @3@1.6  @1@2 1/2@1 @4 3/4
3@Melanistic@3@4@2@4@1 1/2@4@2 3/4@3@5    @2 @4 3/4
2@Pure      @4@5@5@5@3 1/2@5@4 3/4@5@8    @3 @6 1/2
4@Profit    @2@2@1@2@1.6  @1@1.6  @2@2 1/2@4 @6 1/2
1@Whammy    @1@1@1@1@1.6  @2@1.6  @4@5 1/2@5 @8 1/4

答案 1 :(得分:0)

如果我理解正确,那么这个awk one liner将按照你的意愿行事!!

awk -F@ -v OFS="@" 'NR==1{$12=$12-10; $13=$13-10 " 3/4";}{$11=$11" "; sub(" ", "", $12);}1'

输出:

5@Comedia   @5@3@2@3@1/2  @3@1.6  @1@2 1/2 @1@4 3/4
3@Melanistic@3@4@2@4@1 1/2@4@2 3/4@3@5     @2@4 3/4
2@Pure      @4@5@5@5@3 1/2@5@4 3/4@5@8     @3@6 1/2
4@Profit    @2@2@1@2@1.6  @1@1.6  @2@2 1/2 @4@6 1/2
1@Whammy    @1@1@1@1@1.6  @2@1.6  @4@5 1/2 @5@8 1/4

答案 2 :(得分:-1)

您可以将所有这三个命令组合在一行中。如下:

LENGTH=$(cat sample.txt |awk -F@ 'NR==2{print $NF}') awk -F@ -v l="$length" 'NR==1{$(NF-1)=1;$NF=l;print $0}' OFS=@ sample.txt ; awk -F@ 'NR>1{print $0}' sample.txt