2012-03-17 86 views
1

我想使用awk读取格式化文件。内容如下所示:使用awk格式化读取

1PS1  A1 1 11.197 5.497 7.783 
    1PS1  A1 1 11.189 5.846 7.700 
    . 
    . 
    . 

以下的C格式,这些线是按以下格式 “%5D%5S%5S%5D%8.3f%.3f%8.3f” 其中,前5位是整数(1),接下来的5个位置是字符(PS1),接下来的5个位置是字符(A1),接下来的5个位置是整数(1),接下来的24个位置分成3列8个位置,带有3个小数点浮点数。

我一直在用的只是用“$ 1,$ 2,$ 3”来调用这些由行分隔的行。例如,

cat test.gro | awk 'BEGIN{i=0} {MolID[i]=$1; id[i]=$2; num[i]=$3; x[i]=$4; 
y[i]=$5; z[i]=$6; i++} END { ...} >test1.gro 

但我遇到了一些问题,这一点,我现在想如上面所讨论的格式化方式来阅读这些文件。

任何想法如何做到这一点?

回答

2

看看你的示例输入,看起来格式字符串实际上是"%5d%-5s%5s%5d%8.3f%.3f%8.3f",第一个字符串字段是左对齐的。这太糟糕了awk没有一个scanf()功能,但你可以用几个substr()电话让您的数据

awk -v OFS=: ' 
    { 
    a=substr($0,1,5) 
    b=substr($0,6,5) 
    c=substr($0,11,5) 
    d=substr($0,16,5) 
    e=substr($0,21,8) 
    f=substr($0,29,8) 
    g=substr($0,37,8) 
    print a,b,c,d,e,f,g 
    } 
' 

输出

1:PS1 : A1: 1: 11.197: 5.497: 7.783 
    1:PS1 : A1: 1: 11.189: 5.846: 7.700 

如果你有GNU AWK,您可以使用FIELDWIDTHS变量像这样:

gawk -v FIELDWIDTHS="5 5 5 5 8 8 8" -v OFS=: '{print $1, $2, $3, $4, $5, $6, $7}' 

还输出

1:PS1 : A1: 1: 11.197: 5.497: 7.783 
    1:PS1 : A1: 1: 11.189: 5.846: 7.700 
1

你从来没有说过你认为哪个字段应该有什么数字,所以我想清楚地知道awk是如何工作的(你选择明确地在输出格式字符串字段中调用空格会让我担心一点点,你可能对此有不同的想法,比awk)。

从手册页:

输入线通常是由空格, 分隔的字段的或由正则表达式FS。这些字段表示为$ 1,$ 2,...,而 $ 0表示整行。如果FS为空,则输入行将被拆分为每个字符一个字段,即 。

请注意,输入行中的空格未指定字段编号,并且该顺序空白符被视为单个字段分隔符。在命令行

echo "1 2 3 4" | awk '{print "1:" $1 "\t2:" $2 "\t3:" $3 "\t4:" $4}' 

你可以像进行测试。


所有这一切都假定你没有diddles的FS变量,当然。

+0

谢谢。其实,我忘了我可以用gawk使用FIELDWIDTHS选项。 – Greg 2012-03-17 18:56:00

+0

@Greg:如果是'FIELDWIDTHS'解决了你的问题,你不应该接受格伦的答案吗? – dmckee 2012-03-17 19:39:07

+0

谢谢dmckee,进行更正。 – Greg 2012-03-17 21:05:26