【问题标题】:Filtering a CSV file with AWK使用 AWK 过滤 CSV 文件
【发布时间】:2015-04-08 00:16:05
【问题描述】:

我有一个包含大量数据的 CSV 文件。我想有选择地过滤它,我试过这个:

#!/bin/bash

cat my_file.csv | while read line
do

     awk_variables=`echo "$line" | awk -F, '( $13 == "*OUT*" ) || ( $13 == "*IN*" ) {print $1, $5, $10, $12, $13}'`
     echo "$awk_variables" >> my_file.csv

done

数据的sn-p:

1427783525,e,gf,StackExchange,HDCU3000623,d,scan,211,47969,60,1420739235,Sensor,Module,v1.06,1,*IN*
1426661348,e,gf,StackExchange,HDCU3000623,d,scan,197,48066,3,1420703835,Sensor,Module,v1.06,2,*OUT*
1426661355,e,gf,StackExchange,HDCU3000623,d,scan,197,54949,4,1420703822,*OUT*
1426661362,e,gf,StackExchange,HDCU3000623,d,scan,197,61971,5,1420703835,Sensor,Module,v1.06,4,*OUT*
1426661369,e,gf,StackExchange,HDCU3000623,d,scan,197,68947,6,1420705615,*OUT*
1426661376,e,gf,StackExchange,HDCU3000623,d,scan,197,75948,7,1420706218,*OUT*
1426661383,e,gf,StackExchange,HDCU3000623,d,scan,197,82948,8,1420707784,*OUT*
1426661390,e,gf,StackExchange,HDCU3000623,d,scan,197,89947,9,1420707801,*OUT*
1426661397,e,gf,StackExchange,HDCU3000623,d,scan,197,96969,10,1420708035,Sensor,Module,v1.06,9,*OUT*
1426740345,e,gf,StackExchange,HDCU3000623,d,scan,198,47971,11,1420708635,Sensor,Module,v1.06,1,*OUT*
1426740352,e,gf,StackExchange,HDCU3000623,d,scan,198,54964,12,1420708646,H11HDCU3000623,*OUT*
1426740359,e,gf,StackExchange,HDCU3000623,d,scan,198,61963,13,1420708647,H11HDCU3000623,*OUT*
1426740366,e,gf,StackExchange,HDCU3000623,d,scan,198,68963,14,1420708648,H11HDCU3000623,*OUT*
1426740379,e,gf,StackExchange,HDCU3000623,d,scan,198,82948,15,1420708700,*OUT*
1426740493,e,gf,StackExchange,HDCU3000623,d,status,199,44000,Run,#199.,Scans,to,date:,0
1426740497,e,gf,StackExchange,HDCU3000623,d,scan,199,47971,16,1420708635,Sensor,Module,v1.06,1,*OUT*
1426740504,e,gf,StackExchange,HDCU3000623,d,scan,199,54963,17,1420708649,H11HDCU3000623,*OUT*
1426740700,e,gf,StackExchange,HDCU3000623,d,scan,199,250950,18,1420708871,H07W770275,*OUT*
1426740710,m,gf,TMX6BP,075,d,SVlts,288,33604,27352,27352,948
1426740721,m,gf,TMX6BP,075,d,status,288,44000,183139,-33.836465,151.051189
1426740721,e,gf,StackExchange,HDCU3000623,d,scan,199,271941,19,1420708887,H07W770275,*OUT*
1426740728,e,gf,StackExchange,HDCU3000623,d,scan,199,278941,20,1420708888,H07W770275,*OUT*

问题是当我打开 my_file.csv 文件时,数据会按照我的意愿进行过滤 - 但是 有很多空行。这些空行是该行不符合 awk 条件的结果。如何修改上述代码,使过滤后的数据从第一行开始写入?

所以我的输出是:

1426740504 HDCU3000623 17 H11HDCU3000623 *OUT*
1426740700 HDCU3000623 18 H07W770275 *OUT*


1426740721 HDCU3000623 19 H07W770275 *OUT*







1426740728 HDCU3000623 20 H07W770275 *OUT*

【问题讨论】:

  • 哎哟! awk可以读取文件;你不需要cat | while read line; do var=$(echo "$line" | awk ...) 的东西。 awk ... file.csv > file.csv 够用了!
  • @JonathanLeffer,哦!我还在学习!所以我会和 cat 一起摆脱 while 循环 - ?
  • 是的;没有循环;没有猫;没有回声。 awk 只需来自 shell 的一点 I/O(输出)重定向帮助即可完成所有工作。
  • 请注意,我的第一条评论有awk 阅读 写入file.csv。那是行不通的;文件名需要引用不同的文件。就目前而言,在awk 读取它之前输入是空的——不好。
  • 是的。我写了我的评论;他几乎在同一时间写下了他的答案。他得到了我的支持,因为这就是我的意思。

标签: bash csv awk


【解决方案1】:

echo 每次使用时都会打印一个新行。最好不要逐行使用 awk,而是像这样:

awk -F, '($13=="*OUT*")||($13=="*IN*"){print $1,$5,$10,$12,$13}' jacon_mqtt.csv > my_file.csv 

【讨论】:

  • 我不明白为什么,但是当我 echo 出 $13 时,我得到了 =*OUT*,而我应该只得到 *OUT* = 会从哪里附加自己?
  • @JID 这将不起作用,因为字段 $13 中有 *。应该是$13~/^*(IN|OUT)*$/。如果前面和结尾总是有*,可以省略anchor:$13~/*(IN|OUT)*/
  • @Jotne:您的正则表达式中的第二个星需要转义,否则它允许零个或多个括号中的术语。另一颗星不需要反斜杠,因为它不需要重复。
  • @JonathanLeffler Ups,确实错过了。谢谢你。 $13~/^*(IN|OUT)\*$/
猜你喜欢
  • 2021-05-08
  • 1970-01-01
  • 2017-11-10
  • 2018-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2013-07-19
相关资源
最近更新 更多