bash:如何从变量行长度的CSV文件中获取一列?

时间:2012-02-01 17:30:20

标签: bash csv

我有2个CSV文件:a.txt包含数据,a_props.txt描述列的类型,例如:

A.TXT:

john,smith,jsmith@gmail.com,30,
peter,jones,27

a_props.txt:

name,surname,email,age
name,surname,age

如何根据从a_props.txt获取的索引从a.txt获取一种数据?

例如:年龄

30,27

30
27

4 个答案:

答案 0 :(得分:3)

您可以使用paste逐行合并这两个文件,并awk检查您要查找的属性名称是否匹配:

paste -d, a_props.txt a.txt | awk -v PROP='age' -v FS=',' '{for (i=1; i<=NF/2; i++) if ($i == PROP) print $(NF/2+i)}'

在此示例中,输出为:

30
27

请注意,您只需更改PROP=<property>即可获取其他列的值。

编辑:修正了PROP不是记录的最后一个字段的情况。

答案 1 :(得分:1)

使用进程替换和额外的FD来获取要读取的其他流,并并行读取道具和数据文件:

key=age

exec 9< <(tr , " " < a_props.txt) 10< <( tr , " " < a.txt )

while read -u 9 -a props ; do
  read -u 10 -a data
  for (( ix=0 ; $ix < ${#props[*]} ; ix++ )); do
      if [ "${props[$ix]}" == $key ]; then
          echo ${data[$ix]}
      fi
 done 
done 

流程替换是特定于bash的,并且不会在vanilla sh。

中工作

另外,要非常小心一下&#34; csv&#34;文件是。一旦添加了引用字段等,它们就变得难以解析。在那时,我使用其他语言的现有csv包(例如,perl中的Text::CSV或tcllib中的csv包)

答案 2 :(得分:1)

这可能对您有用:

paste a_props.txt a.txt | 
awk '{split($1,a,",");split($2,b,",");for(x in a){if(a[x]==v)print b[x]}}' v=age

答案 3 :(得分:0)

awk -F "," '{ a=1 
              while ((getline p < ARGV[2]) > 0) {
                  props[a]=
                  a++
              }
              close(ARGV[2])
            }
            ARGIND > 1 { exit }
            { for (elem in props) {
                   if (length(props[elem]) = NF) {
                       split(props[elem],header,",")
                       for (item in header) {
                           data[header[item]+=$i ","
                       }
                    }
             }
             END { 
                   for (elem in data) {
                       split(gensub(",$","","g",data[elem]),d,",")
                       print elem ":"
                       for ( e in d ) {
                           print d[e]
                       }
                   }
                 }' a.txt a.props.txt

这可能有用,但我没有测试过。我不建议使用非常大的文件,因为脚本会将它们放入内存中。如果a_props.txt包含两个或多个具有相同字段长度的行,例如:

,会发生什么
name,age
name,email

此案例在上述脚本中处理 !并且脚本的参数顺序是 important