从多个文件复制一行并粘贴为新文件中的列

时间:2015-08-11 08:58:27

标签: linux shell awk

我的文件很少:

ifile1.txt       ifile2.txt       ifile3.txt
3  5  2  2       1  2  1  3       4  3  4  1 
1  4  2  1       1  3  0  2       5  3  1  5 
4  6  5  2       2  5  5  1       3  4  3  1 
5  5  7  1       0  0  1  1       4  3  4  0 
2  3  2  4       3  2  4  1       3  1  2  1

我需要从每个文件中复制第4行并将其作为列粘贴到ofile.txt中:

ofile.txt
5    0   4
5    0   3
7    1   4
1    1   0

我能够通过以下方式实现,但寻找直接/简短的方法。

我首先使用awk

将每个文件的行转换为列
awk '{ 
for (i=1; i<=NF; i++)  {
a[NR,i] = $i
}
}
NF>p { p = NF }
END {    
for(j=1; j<=p; j++) {
str=a[1,j]
for(i=2; i<=NR; i++){
    str=str" "a[i,j];
}
print str
}
}' ifile1.txt > ofile1.txt

然后我使用了paste命令作为

paste ofile* > ofile.txt

最后再次使用awk打印所需的列。

3 个答案:

答案 0 :(得分:4)

Deepu中提及his good answer,说FNR==4足以在每个文件上打印第四行:

awk 'FNR==4' files*

这样就可以得到像

这样的东西
5  5  7  1
0  0  1  1
4  3  4  0

现在你只需要转置数组。为此,我创建了一个小脚本some time ago,我将其命名为transpose(非常擅长名字,我知道):

transpose () {
awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max<NF?NF:max)}
        END {for (i=1; i<=max; i++)
            {for (j=1; j<=NR; j++) 
                printf "%s%s", a[i,j], (j<NR?OFS:ORS)
            }
        }'
}

总之,你只需要说:

$ awk 'FNR==4' f* | transpose
5 0 4
5 0 3
7 1 4
1 1 0

请注意,如果您希望保留格式,可以设置输入和输出字段分隔符(我猜它们现在是制表符分隔符。)

答案 1 :(得分:2)

awk 'FNR == 4 {print}'将从文本文件中打印第四行。

您可以使用重定向运算符>和连接运算符>>来附加来自不同文件的数据。

答案 2 :(得分:1)

如果您的数据是常规的,这是另一种转置方式

tr ' ' '\n' <file | pr -"$n"ts" "

其中n是文件中的行数(转置版本中的列)n可以指定为

 n=$(wc -l file | cut -d" " -f1)

您的脚本可以简化为

 awk 'FNR==4' ifile*.txt > temp
 n=$(wc -l temp | cut -d" " -f1)
 tr ' ' '\n' <temp | pr -"$n"ts" " > ofile.txt