2017-09-27 53 views
0

我有一個CSV日誌文件,記錄屬性HA;HB;HC;HD;HE。以下文件記錄了6個條目(由上述標題分隔)。使用Linux命令進行復雜的CSV解析

我想提取每個條目的第3個屬性(HC)。

HA;HB;HC;HD;HE 
a1;b1;14;d;e 
HA;HB;HC;HD;HE 
a2;b2;28;d;e 
HA;HB;HC;HD;HE 
a31;b31;44;d;e 
a32;b32;07;d;e 
HA;HB;HC;HD;HE 
a4;b4;0;d;e 
HA;HB;HC;HD;HE 
a51;b51;32;d;e 
a52;b52;0;d;e 
a53;b53;5;d;e 
HA;HB;HC;HD;HE 
a6;b6;10;d;e 

每當有nHC每個條目記錄,我想提取添加n條目。

預期輸出上述文件:

14 
28 
51 
0 
37 
10 

我知道我可以寫這樣的程序,但有一個簡單的方法與組合來得到這個在awk和/或sed命令?

回答

1

我沒有測試過這個;試試吧,讓我知道它是否有效。

awk -F';' ' 
    $3 == "HC" { 
     if (NR > 1) { 
      print sum 
      sum = 0 } 
     next } 
    { sum += $3 } 
    END { print sum }' 
+0

這將返回7個零。但讓我打一點點這種想法,看看我能得到它的工作。 – kami

0
awk -F';' '/^H.*/{if(f)print s;s=0;f=$3=="HC"}f{s+=$3}END{if(f)print s}' infile 

對於給定的輸入:

$ cat infile 
HA;HB;HC;HD;HE 
a1;b1;14;d;e 
HA;HB;HC;HD;HE 
a2;b2;28;d;e 
HA;HB;HC;HD;HE 
a31;b31;44;d;e 
a32;b32;07;d;e 
HA;HB;HC;HD;HE 
a4;b4;0;d;e 
HA;HB;HC;HD;HE 
a51;b51;32;d;e 
a52;b52;0;d;e 
a53;b53;5;d;e 
HA;HB;HC;HD;HE 
a6;b6;10;d;e 

$ awk -F';' '/^H.*/{if(f)print s; s=0; f=$3=="HC"}f{s+=$3}END{if(f)print s}' infile 
14 
28 
51 
0 
37 
10 

這需要一點關懷,例如:

$ cat infile2 
HA;HB;HC;HD;HE 
a1;b1;14;d;e 
HA;HB;HC;HD;HE 
a2;b2;28;d;e 
HA;HB;HC;HD;HE 
a31;b31;44;d;e 
a32;b32;07;d;e 
HA;HB;HC;HD;HE 
a4;b4;0;d;e 
HA;HB;HD;HD;HE   <---- Say if HC does not found 
a51;b51;32;d;e 
a52;b52;0;d;e 
a53;b53;5;d;e 
HA;HB;HC;HD;HE 
a6;b6;10;d;e 

# find only HC in 3rd column 
$ awk -F';' '/^H.*/{if(f)print s; s=0; f=$3=="HC"}f{s+=$3}END{if(f)print s}' infile2 
14 
28 
51 
0 
10 

# Find HD in 3rd column 
$ awk -F';' '/^H.*/{if(f)print s; s=0; f=$3=="HD"}f{s+=$3}END{if(f)print s}' infile2 
37 
0
eval "true || $(cat data.csv|cut -d ";" -f3 |sed -e s/"HC"/"0; expr 0"/g |tr '\n' '@'|sed -e s/"@@"/""/g|sed -e s/"@"/" + "/g)" 

說明:

  1. 使用cat獲取文件的內容
  2. 採取只使用cut分隔符的;
  3. 第三列與0; expr 0值替換HC線開建eval -worthy bash的表達式,最終產生expr 0 + 14;
  4. 更換\n換行@繞過可能的BSD sed限制
  5. 將雙@@替換爲單個@,以避免空行變成空格並導致expr炸燬。
  6. @替換爲+以將數字相加。
  7. 執行該命令,但使用true || 0; expr ...以避免在第一行保留語法錯誤。

它創建這樣的:

true || 0; expr 0 + 14 + 0; expr 0 + 28 + 0; expr 0 + 44 + 07 + 0; expr 0 + 0 + 0; expr 0 + 32 + 0 + 5 + 0; expr 0 + 10 

輸出看起來是這樣的:

14 
28 
51 
0 
37 
10 

這是巴蜀3.2和MacOS埃爾卡皮坦測試。

1

awk的解決方案:

$ awk -F';' '$3=="HC" && p{ 
    print sum   # print current total 
    sum=p=0   # reinitialize sum and p 
    next 
} 
$3!="HC"{ 
    sum=sum+($3+0)  # make sure $3 is converted to integer. sum it up. 
    p=1    # set p to 1    
}      # print last sum 
END{print sum}' input.txt 

輸出:

14 
28 
51 
0 
37 
10 

一行代碼:

$ awk -F";" '$3=="HC" && p{print sum;sum=p=0;next} $3!="HC"{sum=sum+($3+0);p=1} END{print sum}' input.txt 
0

能否請您嘗試以下,讓我知道,如果這可以幫助你。

awk -F";" ' 
/^H/ && $3!="HC"{ 
    flag=""; 
    next 
} 
/^H/ && $3=="HC"{ 
    if(NR>1){ 
    printf("%d\n",sum) 
}; 
    sum=0; 
    flag=1; 
    next 
} 
flag{ 
    sum+=$3 
} 
END{ 
    printf("%d\n",sum) 
} 
' Input_file 

輸出如下。

14 
28 
51 
0 
37 
10 
0
$ awk -F';' '$3=="HC"{if (NR>1) print s; s=0; next} {s+=$3} END{print s}' file 
14 
28 
51 
0 
37 
10