我正在尝试使用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
但是我遇到了一些问题,现在我正试图以上面讨论的格式化方式阅读这些文件。
知道我是怎么做到的吗?
答案 0 :(得分: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 :(得分:1)
你从来没有确切地说过你认为哪些字段应该包含哪个数字,所以我想清楚awk
如何认为有效(你选择明确在输出格式字符串字段中调用空格)让我担心一点。你可能对此有一个不同的想法,而不是awk
。)。
从联系手册:
输入行通常由用空格分隔的字段组成, 或者通过正则表达式FS。这些字段表示为$ 1,$ 2,...,而 $ 0指整行。如果FS为null,则输入行被拆分 每个角色一个字段。
请注意,输入行中的空格不会被赋予字段编号,而连续的空格将被视为单个字段分隔符。
您可以使用以下内容对此进行测试:
echo "1 2 3 4" | awk '{print "1:" $1 "\t2:" $2 "\t3:" $3 "\t4:" $4}'
在命令行。
所有这些都假设您当然没有使用FS
变量。