2017-03-04 16 views
0

我的腳本獲取dir中的每個.csv文件並將它們一起寫入新文件。它還編輯這些文件,以便將某些信息寫入每個文件條目的每一行中。例如該文件名爲 「trap10c_7C000000395C1641_160110.csv」:在解析過程中從文件中刪除標題

"",1/10/2016 
"Timezone",-6 

"Serial No.","7C000000395C1641" 
"Location:","LS_trap_10c" 
"High temperature limit (�C)",20.04 
"Low temperature limit (�C)",-0.02 
"Date - Time","Temperature (�C)" 
"8/10/2015 16:00",30.0 
"8/10/2015 18:00",26.0 
"8/10/2015 20:00",24.5 
"8/10/2015 22:00",24.0 

被轉換成這種格式

LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,Location:,LS_trap_10c 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,High,temperature,limit,(�C),20.04 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,Low,temperature,limit,(�C),-0.02 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,Date,-,Time,Temperature,(�C) 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,8/10/2015,16:00,30.0 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,8/10/2015,18:00,26.0 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,8/10/2015,20:00,24.5 
LS_trap_10c,7C000000395C1641,trap10c_7C000000395C1641_160110.csv,8/10/2015,22:00,24.0 

我使用這個腳本來做到這一點:

dos2unix *.csv 
gawk '{print FILENAME, $0}' *.csv>>all_master.erin 
sed -i 's/Serial No./SerialNo./g' all_master.erin 
sed -i 's/ /,/g' all_master.erin 
gawk -F, '/"SerialNo."/ {sn = $3} 
     /"Location:"/ {loc = $3} 
     /"([0-9]{1,2}\/){2}[0-9]{4} [0-9]{2}:[0-9]{2}"/ {lin = $0} 
         {$0 =loc FS sn FS $0}1' all_master.erin > formatted_log.csv 
sed -i 's/\"//g' formatted_log.csv 
sed -i '/^,/ d' formatted_log.csv 
rm all_master.erin 
printf "\nDone\n" 

我想刪除來自formatted_log.csv文件的雜亂標題。我試過並沒有使用sed,因爲它似乎刪除了我不想刪除的內容。 sed是解決這個問題的最好方法嗎?目前的sed修復了頭部的一些問題,但我希望頭部完全消失。任何表示「序列號」的行和「位置」很重要,需要信息。其他行可以完全刪除。

回答

1

我想你在發佈前編輯的腳本;按照現狀,它不會生成張貼的輸出(all_master.erin應該是$(<all_master.erin),第一次出現除外)。

您沒有指定輸入文件格式的許多重要細節,所以我們必須猜測它們。這是我的猜測:

  • 您忽略前兩行和後續的空第三行。

  • 第四和第五行是有用的,因爲它們提供要在該文件

  • 第六的所有線路使用的序列號和位置,第7和第8號線是無用的。

  • 對於每個文件,您想要放棄發佈的輸出的前四行。

根據這些假設,這是我怎麼會修改你的腳本:

#!/bin/bash 
dos2unix *.csv 
awk -vFS=, -vOFS=, \ 
    '{gsub("\"","")} 
    FNR==4{s=$2} 
    FNR==5{l=$2} 
    FNR>8{gsub(" ",OFS);print l,s,FILENAME,$0}' \ 
    *.csv > formatted_log.CSV 
printf "\nDone\n" 

awk腳本的說明:

首先,我們刪除所有雙引號gsub("\"","")。然後,如果行號是4,我們將變量s設置爲第二個字段,即序列號。如果行號是5,我們將變量l設置爲第二個字段,即位置。如果行號大於8,我們做兩件事。首先,我們執行gsub(" ",OFS)以將所有空格替換爲輸出字段分隔符的值:這是必需的,因爲預期的輸出會生成兩個單獨的日期和時間字段,這兩個字段只是輸入中的一個字段。其次,我們按要求打印以lsFILENAME的值開頭的行。

請注意,我使用的命名輸出文件的(可疑的)Unix技巧帶有全部擴展名擴展名.CSV,以避免它被隨後的*.csv錯誤地匹配。更好的解決方案是把它放在另一個目錄中,但我對你的目錄樹一無所知,所以我建議你自己修改輸出文件名。

+0

你能解釋一下FNR> 8 {gsub(「」,OFS); print l,s,FILENAME,$ 0}'\ 是嗎? – 5r9n

+0

@Erin看到編輯答案。 – Dario

1

你可以用awk在最終文件少於3列,刪除任何 :

awk 'NF>=3' file

+0

這是一個好主意,但它似乎沒有對我的文件做任何事情。 – 5r9n

+0

我應該添加一個編輯到位選項嗎? – 5r9n