我有一个固定宽度的数据文件,如下所示:
ATOM 6181 H4 BGLC 2 -6.078 -11.556 0.599 1.00 0.00
ATOM 6182 O4 BGLC 2 -5.410 -10.816 2.307 1.00 7.76
ATOM 6183 C6 BGLC 2 -8.313 -11.233 1.955 1.00 8.41
ATOM 6184 H61 BGLC 2 -9.308 -11.734 2.225 1.00 0.00
ATOM 6185 H62 BGLC 2 -8.302 -10.340 2.573 1.00 0.00
ATOM 6186 O6 BGLC 2 -8.412 -11.033 0.547 1.00 8.44
ATOM 6187 HO6 BGLC 2 -7.623 -10.829 0.055 1.00 0.00
ATOM 6188 C1 BGLC 3 -4.821 -9.797 1.481 1.00 7.45
ATOM 6189 H1 BGLC 3 -5.419 -9.613 0.596 1.00 0.00
我正在尝试将最后两列替换为其他变量charge
和radius
。我尝试使用cut来挑选该行的前54个字符(前8列),然后使用echo将charge
和radius
添加到最后,如下所示:
newline=$(echo $(echo $pqratomline | cut -c 1-54) $charge $radius)
其中pqratomline
是一个等于文件中特定行的字符串。但是,echo会消除额外的空白,从而抛出固定宽度的列。
有没有人建议如何在不使用echo的情况下执行此操作,或者保持echo不会删除额外的空格?
修改 我希望得到这样的东西(只显示前几行):
ATOM 6181 H4 BGLC 2 -6.078 -11.556 0.599 0.0900 1.3400
ATOM 6182 O4 BGLC 2 -5.410 -10.816 2.307 -0.6500 1.7650
相反,我得到了:
ATOM 6181 H4 BGLC 2 -6.078 -11.556 0.599 0.0900 1.3400
ATOM 6182 O4 BGLC 2 -5.410 -10.816 2.307 -0.6500 1.7650
答案 0 :(得分:1)
作为替代方案,您可以使用printf
代替echo
,因为printf
具有更好的行为,您还可以调整每个打印变量的宽度:
$ echo "$a"
ATOM 6179 HO3 BGLC 2 -3.020 -13.471 0.981 1.00 0.00
$ charge="2.22";radius="2.22"
$ newline=$(printf '%s%6s%6s\n' "$(echo "$a" | cut -c 1-54)" "$charge" "$radius");echo "$newline"
ATOM 6179 HO3 BGLC 2 -3.020 -13.471 0.981 2.22 2.22
%6s
中的printf
格式指示要以6个字符宽度打印的变量。
类似地:
$ echo "$a"
ATOM 6179 HO3 BGLC 2 -3.020 -13.471 0.981 1.00 0.00
$ charge="0.0900";radius="1.3400"
$ newline=$(printf '%s%12s%12s\n' "$(echo "$a" | cut -c 1-54)" "$charge" "$radius");echo "$newline"
ATOM 6179 HO3 BGLC 2 -3.020 -13.471 0.981 0.0900 1.3400
您可以根据需要调整新字段宽度(%12s
以上)的值。
答案 1 :(得分:0)
假设您的费用和半径变量不包含反向引用或/ s或其他任何可能关心的内容:
$ charge=7
$ radius=2.5
$ sed 's/[^ ]*\( *\)[^ ]*$/'"$charge"'\1'"$radius"'/' file
ATOM 6181 H4 BGLC 2 -6.078 -11.556 0.599 7 2.5
ATOM 6182 O4 BGLC 2 -5.410 -10.816 2.307 7 2.5
请注意,您发布的预期输出不会遵循与输入相同的固定宽度布局(它会保留最后2个字段之间的间距,但会扩展每个字段占用的空间),因此上述解决方案也不会。
答案 2 :(得分:-1)
awk的一个问题是,除非你特别注意准备输出格式,否则它会删除空格,从而破坏你的固定宽度间距。
awk -v charge="$charge" -v radius="$radius" '
{
printf "%54s%8.4f%8.4f\n", substr($0,1,54), charge, radius
}
' input.txt
这使用awk的-v
选项将环境变量插入到awk脚本中。
当然,您可以在bash中执行此操作并使用参数扩展来去除您不想要的行的部分...
while read line; do
lhs=${line:0:54} # The first 54 characters...
rhs=${line:54} # in case you need these for later...
printf '%s%8.4f%8.4f\n' "$lhs" "$charge" "$radius"
done < input.txt