如果大于、小于或等于 0,则根据第一列输出到最后一列

如果大于、小于或等于 0,则根据第一列输出到最后一列

我有一个大的 .csv(逗号分隔,超过 90,000 行),格式如下所示:

x坐标,m1,m2,m3
9、对、错、错
-1,对,错,错
0,对,错,错

我能够在末尾添加一个带有 AMT 标题的额外列,以允许写入最后一个字段:

Source_File="/test/Orders_ALL.csv"
Output_File="/test/Orders_ALL_MODIFIED.csv"
awk -vd="BMT" -F"," 'BEGIN { OFS = "," } {$5=d;打印}'“$Source_File”>“$Output_File”

上述结果之后的输出:

x坐标,m1,m2,m3,BMT
9、正确、错误、错误、基础医学理论
-1,对,错,错,BMT
0,对,错,错,基本MT

我想要完成的任务是读取从第二行开始的第一列值,如果小于 0,它将写入单词“BEHIND”,如果是 0,则打印单词“MID”,如果是更大的值大于 0,则打印单词“THROUGH”

这是期望的结果:

x坐标,m1,m2,m3,BMT
9、真、假、假、通过
-1,正确,错误,错误,后面
0、真、假、假、中

答案1

$ awk 'BEGIN { OFS=FS="," } $1<0 { t="BEHIND" } $1==0 { t="MID" } $1>0 { t="THROUGH" } NR==1 { t="BMT" } { print $0, t }' file.csv
xcoord,m1,m2,m3,BMT
9,TRUE,FALSE,FALSE,THROUGH
-1,TRUE,FALSE,FALSE,BEHIND
0,TRUE,FALSE,FALSE,MID

该代码首先将输入和输出字段分隔符设置为逗号。然后它作用于第一列的值,将变量设置t为正确的值。如果我们查看输入的第一行,t则将其设置为BMT(无论之前设置为什么)。然后我们将当前行打印为t末尾的新字段。

格式稍微好一点:

awk 'BEGIN   { OFS = FS = "," }
     $1 <  0 { t = "BEHIND"   }
     $1 == 0 { t = "MID"      }
     $1 >  0 { t = "THROUGH"  }
     NR == 1 { t = "BMT"      }
             { print $0, t    }' file.csv

使用 Perl:

$ perl -lane 'BEGIN { @t=(qw(BEHIND MID THROUGH)) } printf("%s,%s\n", $_, $. == 1 ? "BMT" : $t[1+($F[-1] <=> 0)])' file.csv
xcoord,m1,m2,m3,BMT
9,TRUE,FALSE,FALSE,THROUGH
-1,TRUE,FALSE,FALSE,BEHIND
0,TRUE,FALSE,FALSE,MID

Perl<=>运算符(有时称为“宇宙飞船运算符”)进行三向算术比较。当左侧严格小于右侧时,返回-1,如果相等,则返回0,否则返回1。

答案2

$ awk -F, 'BEGIN { OFS="," } NR==1 { print $0, "BMT" } NR>1  && $1>0 { print $0, "THROUGH" } NR>1 && $1==0 { print $0, "MID" } NR>1 && $1<0 { print $0, "BEHIND" }' inputfile > outputfile

或者,另一种选择:

$ awk -F, 'BEGIN { OFS="," } NR==1 { print $0, "BMT" } NR>1 { if( $1 < 0 ) { $5="BEHIND" }; if( $1==0 ) { $5="MID" }; if( $1>0 ) { $5="THROUGH" }; print }' inputfile > outputfile

实际的awk脚本重新格式化以便于阅读(我在这里将扩展后一个版本):

BEGIN { 
    OFS="," # Set the Output Field Separator.  
            # This is the complement to `F,` which 
            # sets the Input Field Separator.
} 

NR==1 {  # For only the first record
    print $0, "BMT" # Print exactly what we got, but add a new field, BMT
} 

NR>1 {   # For all records _after_ the first:
    if( $1 < 0 ) {    # This and the other if statements check
        $5="BEHIND"   # the value of the first field, and set
    };                # the value of the to-be-newly-added fifth 
    if( $1==0 ) {     # field accordingly. 
        $5="MID" 
    }; 
    if( $1>0 ) { 
        $5="THROUGH" 
    }; 
    print             # Finally, print all our fields
}

答案3

与米勒(http://johnkerl.org/miller/doc

mlr --csv put 'if ($xcoord < 0) {$BMT="BEHIND"};
if ($xcoord == 0) {$BMT="MID"};
if ($xcoord > 0) {$BMT="THROUGH"}' input >./output

你有

xcoord,m1,m2,m3,BMT
9,TRUE,FALSE,FALSE,THROUGH
-1,TRUE,FALSE,FALSE,BEHIND
0,TRUE,FALSE,FALSE,MID

作为我使用过的输入

xcoord,m1,m2,m3
9,TRUE,FALSE,FALSE
-1,TRUE,FALSE,FALSE
0,TRUE,FALSE,FALSE

答案4

 $ perl -F, -pale '$_ .= "," . ("BMT", qw/MID THRU BEHIND/[$F[0] <=> 0])[$. > 1]' csvfile

如果 xcoord 位于第 23 列,请将 $F[0] 替换为 $F[22]

有关解释,请参阅 Kusalananda 的回答,我在其中写了有关 Perl 解决方案的简介。

结果:

 xcoord,m1,m2,m3,BMT
 9,TRUE,FALSE,FALSE,THRU
 -1,TRUE,FALSE,FALSE,BEHIND
 0,TRUE,FALSE,FALSE,MID

xcol=1; # the column number of xcoord
sed -e '
  1s/$/,BMT/;1b
  s/,/\n/'"$xcol"'
  s/.*/,&,/
  /,-[1-9][0-9]*\n/s/$/BEHIND/
  /,0\n/s/$/MID/
  /,[1-9][0-9]*\n/s/$/THRU/
  s/\n/,/;s/,//
 '  csvfile

相关内容