【问题标题】:BashScript: Read a file and process itBash 脚本:读取文件并处理它
【发布时间】:2016-07-17 09:54:28
【问题描述】:

我有一个具有这种结构的文件:

Text...
        A                          B                    C
        A1                   57,624,609,830           20.99
        A2                   49,837,119,260           20.90
        A3                      839,812,303           20.88
        A4                      843,568,192           20.87
        ...                   1,016,104,564           20.82
        A29                   1,364,178,406           16.62
 A line of text
 Blank
 Text
 Text
        A                          B                    C
        A1                   57,624,609,830           20.99
        A2                   49,837,119,260           20.90
        A3                      839,812,303           20.88
        A4                      843,568,192           20.87
        ...                   1,016,104,564           20.82
        A29                   1,364,178,406           16.62 

我想获取所有 A1 及其值,然后是所有 A2 及其值,依此类推。 到目前为止,我正在做的是

cat myFile.csv | awk '{if (NR > 5 && NR <= 29) printf $1"\t"}' > tmp1.csv

我在新文件 tmp1.csv 的不同单元格中得到 A1 A2 A3... 然后

cat myFile.csv | grep A1 | awk '{print $2}'

要获取 A1 的值,请将粘贴复制到 tmp1 文件中的 A1 列。 我试过了

#!/bin/bash
input="myFile.csv"
while IFS= read -r line

do

    awk '{if (NR > 4 && NR <= 28) | grep A1 | awk print $2 }'

done < "$input"

但不能使其产生与

相同的结果
      A1                 A2                 A3              A4        ... 
57,624,609,830     49,837,119,260      839,812,303      839,812,303   ...
57,624,609,830     49,837,119,260      839,812,303      839,812,303   ...
...

在一个文件中。换句话说,从第 5 行到第 28 行,不同单元格中的 $1 和每列中的 $2 对我来说是理想的。

更新

cat myFile.csv | awk '{if (NR > 5 && NR <= 29) printf $1"\t"}'

给我我关心的行的内容。如何在所有行中循环进入整个文件以获取所有内容?例如,而不是

NR&gt;5 &amp;&amp; NR&lt;=29 让 x=1 NR&gt;x+4 &amp;&amp; NR&lt;=x+28 并最终获得内容。

【问题讨论】:

  • 您尝试使用cat ... | grep ... | awk ... 执行的所有操作都可以仅使用 awk 完成。 awk 是一种成熟的编程语言;考虑这样使用它——cat 的目的是连接文件;如果您使用它仅从一个文件中读取,foo &lt;filename [它只是运行命令foo 并在filename 上具有直接、可搜索的句柄] 比cat filename | foo [运行一个副本/usr/bin/catfoo 的副本,它们之间有一个基于 mkpipe 的 FIFO]。
  • ...坦率地说,单独运行 awk -- 没有 bash,没有 grep -- 可能是正确的选择。
  • 你为什么不做类似awk '$1~/^A[0-9]+/ {# here is a line of AXX data...}'

标签: linux bash shell awk terminal


【解决方案1】:

awk 来救援!

$ awk '/A[0-9]+/' file | sed -r 's/^ +//g' | sort -k1.1,1.1 -k1.2n

A1                   57,624,609,830           20.99
A1                   57,624,609,830           20.99
A2                   49,837,119,260           20.90
A2                   49,837,119,260           20.90
A3                      839,812,303           20.88
A3                      839,812,303           20.88
A4                      843,568,192           20.87
A4                      843,568,192           20.87
A29                   1,364,178,406           16.62
A29                   1,364,178,406           16.62

或者如果你的sort 支持版本排序,它也可以工作。您可以通过添加 &amp;&amp; NF==3

来限制模式匹配

如果需要转置布局,可以将第一个脚本的输出通过管道传送到

$ ... | awk 'NR%2{h=h FS $1; r1=r1 FS $2} !(NR%2){r2=r2 FS $2}
              END{print h; print r1; print r2}' | column -t

A1              A2              A3           A4           A29
57,624,609,830  49,837,119,260  839,812,303  843,568,192  1,364,178,406
57,624,609,830  49,837,119,260  839,812,303  843,568,192  1,364,178,406

或将两者合并到一个脚本中,尤其是在您的记录已经排序的情况下。

更新

从原始输入文件开始的组合脚本

$ awk '/A[0-9]+/ && NF==3{if (!a[$1]++) {h=h FS $1; r1=r1 FS $2} else {r2=r2 FS $2}}
                      END{print h; print r1; print r2}' file | 
  column -t

A1              A2              A3           A4           A29
57,624,609,830  49,837,119,260  839,812,303  843,568,192  1,364,178,406
57,624,609,830  49,837,119,260  839,812,303  843,568,192  1,364,178,406

【讨论】:

  • 感谢 karafka 的回答,但这并不是我想要做的。抱歉,如果我不够清楚,我更新了我的问题以更准确。
  • 没问题,我通常会尝试根据我阅读的内容进行推断。查看更新。
  • karafka 当我只使用控制台中的最后一个命令时 (awk '/A[0-9]+/ && NF==3{if (!a[$1]++) {h= h FS $1; r1=r1 FS $2} else {r2=r2 FS $2}} END{print h; print r1; print r2}' myFile.csv | column -t) 什么都不做。如果我删除 '/A[0-9]+/ && 它会输出结果但不在列中。当我在 Excel 中执行 > output.csv 时,我可以看得更清楚,其中所有值都在前两行中。
  • 也许你有更多字段,请删除&amp;&amp; NF==3。它适用于您发布的数据文件。
猜你喜欢
  • 1970-01-01
  • 2014-10-26
  • 2017-04-24
  • 2017-12-04
  • 1970-01-01
  • 2015-11-02
  • 2012-02-14
  • 2020-10-13
  • 1970-01-01
相关资源
最近更新 更多