【问题标题】:How to print rows with a cell value smaller than 0.2 in any of the columns?如何在任何列中打印单元格值小于 0.2 的行?
【发布时间】:2017-07-15 06:13:43
【问题描述】:

我有一个包含 100 多列和 1000 多行的 csv 文件 (myfile.csv),我需要在 至少一个 中打印标题和单元格值小于 0.2 的每一行列(无论哪一列)复制到新文件 (newfile_0.2.csv)。我确实需要整行。

我只能为specific column 找到这样做的方法。

这是我的失败尝试列表(我对编码很陌生):

awk '(NR==1) || ($0 < 0.2 ) ' myfile.csv > newfile_0.2.csv

awk -F "," 'BEGIN $0 < 0.2 {print $0}' myfile.csv > newfile_0.2.csv

awk -F "," '{OFS = ","} BEGIN {$0 < 0.2} {print $0}' myfile.csv > newfile_0.2.csv

awk '{FS = ","} {OFS = ","} BEGIN {$0 < 0.2} {print $0}' myfile.csv > newfile_0.2.csv

awk -F "," '{if ($0 < 0.2) print $0}' myfile.csv > newfile_0.2.csv

while read line; do awk -F "," '{if ($0 < 0.2) print $0}' line ; done < myfile.csv > newfile_0.2.csv

while read line; do echo $line | awk -F "," '{for (i=1;i<=NF;i++) if ($i < 0.2) print $i}'; done < myfile.csv > newfile_0.2.csv

有人知道怎么做吗?谢谢!

【问题讨论】:

  • 可以使用$0访问整行。

标签: csv awk


【解决方案1】:

根据你的努力,我做了这个草图:

# file: script.awk
BEGIN { FS = OFS = "," }
{ # for every row
  hit = 0 ; for (i = 1; i <= NF && !hit; ++i) { if ($i < 0.2) hit = 1 }
  if (hit) print $0
  next
}

示例会话(cygwin、bash、gawk):

$ cat >myfile.csv <<EOF
> 1,1,1,1
> 1,0.1,1,1
> 2,2,2,2
> 0,1,2,3
> 3,3,3,3.0
> EOF

$ awk -f script.awk myfile.csv
1,0.1,1,1
0,1,2,3

也许,您必须确保兼容的 LOCALE。 因此

$ LANG=C

以防万一是个好主意。

玩弄这个我得到了这个(甚至更短的)版本:

# file: script.awk
BEGIN { FS = OFS = "," }
{ # for every row
  for (i = 1; i <= NF; ++i) { if ($i < 0.2) { print $0 ; break } }
}

它也通过了我的测试文件。

...或最终简化为“单线”:

$ awk -F , -v OFS=, '{ for (i = 1; i <= NF; ++i) { if ($i < 0.2) { print $0 ; break } } }' test-filter-0.2.txt
1,0.1,1,1
0,1,2,3

【讨论】:

  • @pdalcinmartins 我不确定next 是否真的有必要。不过,我敢肯定它不会伤害...
  • 你也可以设置OFS=","
  • @pdalcinmartins 因此,next 是不需要的,即不匹配任何规则的行被简单地消耗。 (我记得的实际上是lex/flex 的行为,它只是将任何不匹配的模式反映到yyout。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
  • 1970-01-01
相关资源
最近更新 更多