在解析

时间:2017-03-04 22:59:10

标签: bash parsing sed

我的脚本获取目录中的每个.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修复了标题的一些问题,但我希望标题完全消失。任何说“序列号”的行。和“位置”很重要,需要信息。其他行可以完全删除。

2 个答案:

答案 0 :(得分:1)

您可以使用awk删除任何内容 在最终文件中少于3列:

awk 'NF>=3' file

答案 1 :(得分:1)

我想你在发布之前编辑了你的脚本;就目前而言,它不会产生发布的输出(all_master.erin应该是$(<all_master.erin),除非在第一次出现时)。

您没有指定输入文件格式的许多重要细节,因此我们必须猜测它们。以下是我的猜测:

  • 您忽略前两行和随后的空第三行。

  • 第4行和第5行很有用,因为它们提供了您要在该文件的所有行中使用的序列号和位置

  • 第6,第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错误匹配。一个更好的解决方案是将它放在另一个目录中,但我对你的目录树一无所知,所以我建议你自己修改输出文件名。