简体   繁体   English

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

[英]Declaring variables from data, and running multiple commands on data in one line of code

I've come across an error today and would like other people's opinions on a solution beyond what I have. 今天,我遇到了一个错误,希望别人能提供我所没有的解决方案的意见。 The error is in a dataset. 错误在数据集中。 The data in the last column/field of the first and second row/record should be the same, and the second to last column/field of row/record 1 is always "1". 第一行和第二行/记录的最后一列/字段中的数据应相同,并且行/记录1的倒数第二列/字段始终为“ 1”。 The problem is when this is not so and and the steps needed to correct it. 问题是当情况并非如此时,需要采取纠正措施。

The incorrect data is as such, in a file called "sample.txt": 这样的错误数据就存在于名为“ 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

The correct data should look like this: 正确的数据应如下所示:

 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

My current solution is a multi-step process I have a feeling can be streamlined. 我当前的解决方案是一个多步骤的过程,我有一种可以简化的感觉。 Any suggestions are highly appreciated. 任何建议都将受到高度赞赏。

1)Create a bash variable: 1)创建一个bash变量:

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

2)Create a file with the correct information in row 1: 2)在第1行中创建具有正确信息的文件:

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

3)Append the remaining info to the created correct row file 3)将剩余信息追加到创建的正确行文件中

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

Is there an awk, sed, or Perl one liner (or combinations of pipes) that can accomplish the three steps above in one? 是否有awk,sed或Perl一个内衬(或管道组合)可以一次完成上述三个步骤?

If I have understood you correctly then this program will do as you wish 如果我对您的理解正确,那么该程序将按照您的意愿进行

It reads the first two lines from the file, and replaces the last two fields of the first line with 1 , and the last field from the second line. 它从文件中读取前两行,并将第一行的后两个字段替换为1 ,并将第二行的最后一个字段替换。 Then it prints those two lines and copies the rest of the file 然后打印这两行并复制文件的其余部分

The path to the input file is expected as a parameter on the command line 输入文件的路径应作为命令行上的参数使用

use strict;
use warnings 'all';

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

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

print $line1;
print $line2;

print while <>;

output 输出

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

You can combine all these three commands in one line. 您可以将所有这三个命令合并在一行中。 Like following: 如下所示:

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

If I have understood you correctly then this awk one liner will do as you wish!! 如果我对您的理解正确,那么这款awk班轮将按您的意愿进行!

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

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM