0以上の場合、最初の列に基づいて最後の列に出力

0以上の場合、最初の列に基づいて最後の列に出力

次の形式の大きな.csv(カンマ区切り、90,000行以上)があります。

x座標、m1、m2、m3
9.正しい、間違っている、間違っている
-1、正しい、間違っている、間違っている
0、正しい、間違っている、間違っている

最後のフィールドを作成できるように、最後にAMTヘッダーを持つ追加の列を追加できました。

ソース_ファイル="/test/Orders_ALL.csv"
Output_File="/test/Orders_ALL_MODIFIED.csv"
awk -vd="BMT" -F"," 'BEGIN { OFS = "," } {$5=d;print}'"$Source_File">"$Output_File"

上記の結果の後の出力:

x座標、m1、m2、m3、BMT
9. 正しい、陰、陰、基礎医学理論
-1、正しい、間違っている、間違っている、BMT
0、正しい、間違っている、間違っている、基本MT

私が達成したいのは、2行目から始まる最初の列の値を読むことです。この値が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 -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<=>演算子(時には「宇宙船演算子」とも呼ばれる)は、3方向算術比較を実行します。左辺が右辺よりも厳密に小さい場合は-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]に置き換えます。

説明については、Perl ソリューションの紹介を書いた Kusalananda の回答をご覧ください。

結果:

 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

関連情報