使用sed和awk将多个TXT文件中的列组合到一个表中

时间:2013-12-16 22:10:40

标签: r bash sed awk

我有FileA.txtFileB.txtFileC.txt等文件,其中包含以下列标题:

ID        Value1        Value2        Value3

我想在ID列上组合这些文件中的选择列,将文件名保留为新列标题,所以我得到下表

ID Value1fromFileA Value1fromFileB Value1fromFileC

我可以使用Rldply()函数成功(尽管不是最佳)在cast()中执行此操作。但是,我希望能够通过一些shell脚本执行此操作。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

我确信这可以更快/更好地完成,但下面很简单,如果很长时间,应该可行。只有值得一提的命令是cat file1.txt file2.txt file3.txt | awk '{print $1}' | sort | uniq -c | grep "^[ \t]*3" | awk '{print $2}',它将文件组合在一起,取第一列,生成每个值出现次数的计数,并存储出现3次的值。

#!/bin/bash

trim() {
  t="${1##*( )}"
  t="${t%%*( )}"
  echo "$t"
}

ids=$(cat file1.txt file2.txt file3.txt | awk '{print $1}' | sort |  uniq -c | grep "^[ \t]*3" | awk '{print $2}')

for i in $ids; do
  line1=''
  line2=''
  line3=''
  for file in file1.txt file2.txt file3.txt; do
    while read line; do
      index=$(echo $line | awk '{print $1}')
      #printf "$index\n"
      if [[ $(trim $i) == $(trim $index) ]]; then
        if [[ $line1 == '' ]]; then
          line1="$line"
        elif [[ $line2 == '' ]]; then
          line2="$line"
        else
          line3="$line"
        fi
      fi
    done < "$file"
  done

  echo "$line1 $line2 $line3" | awk '{print $1 " " $5 " " $9}'
done

e.g。

$ cat file1.txt
12 F2Value1 F3Value2 F4
35 F2Value1 F3Value2 F42
2 F2Value1 F3Value2 F43
523 F2Value1 F3Value2 F44
123 F2Value1 F3Value2 F45
$ cat file2.txt
1 F2Value1 F3Value2
12 F2Value1 F3Value2
123 F2Value1 F3Value2
523 F2Value1 F3Value2
99 F2Value1 F3Value2
$ cat file3.txt
72 F2Value1 F3Value2
12 F2Value1 F3Value2
100 F2Value1 F3Value2
111 F2Value1 F3Value2
123 F2Value1 F3Value2

$ ./script.sh
12 F2Value1 F3Value2 F4 F2Value1 F3Value2 F2Value1 F3Value2 
123 F2Value1 F3Value2 F45 F2Value1 F3Value2 F2Value1 F3Value2

上面使用echo“$ line1 $ line2 $ line3”| awk'{print $ 1“”$ 2“”$ 3“”$ 4“”$ 6“”$ 7“”$ 9“”$ 10“”$ 11}'

答案 1 :(得分:1)

awk '{ getline val2<"file2"  # read file "file2" to var "val2" , each time, read one line.
       split(val2,a2,FS);    # split var2 into array a2
    getline val3<"file3"     # read file "file3" to var "val3" , each time, read one line.
    split(val3,b3,FS)        # split var3 into array a3
    print $1,$2,a2[2],b3[2]
}' file1

答案 2 :(得分:1)

您可以尝试:

awk '
{
    q[$1]++
    a[$1,ARGIND]=$2
}

END {
    for (i in q) {
        if (q[i]==3) {
            print i, a[i,1],a[i,2],a[i,3]
        }
    }
} ' FileA.txt FileB.txt FileC.txt

给定文件:FileA.txt

3 A31 A32 A33
5 A51 A52 A53
9 A91 A92 A93

FileB.txt

2 B21 B22 B23
9 B91 B92 B93
4 B41 B42 B43
5 B51 B52 B53

FileC.txt

7 C71 C72 C73
9 C91 C92 C93
5 C51 C52 C53

输出结果为:

5 A51 B51 C51
9 A91 B91 C91