替换固定宽度文件中的单个条目
Replacing Individual Entries in Fixed Width File
我有一个固定宽度的数据文件,如下所示:
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
作为替代方案,您可以使用 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
printf
中的 %6s
格式规定要打印的变量宽度为 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
以上)。
awk 的一个问题是,除非您特别注意准备输出格式,否则它会删除空格,从而破坏您的固定宽度间距。
awk -v charge="$charge" -v radius="$radius" '
{
printf "%54s%8.4f%8.4f\n", substr([=10=],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
假设您的 charge 和 radius 变量不包含反向引用或 /s 或 sed 可能关心的任何其他内容:
$ charge=7
$ radius=2.5
$ sed 's/[^ ]*\( *\)[^ ]*$/'"$charge"''"$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 个字段之间的间距,但扩展了每个字段占用的 space),因此也没有以上解决方案。
我有一个固定宽度的数据文件,如下所示:
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
作为替代方案,您可以使用 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
printf
中的 %6s
格式规定要打印的变量宽度为 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
以上)。
awk 的一个问题是,除非您特别注意准备输出格式,否则它会删除空格,从而破坏您的固定宽度间距。
awk -v charge="$charge" -v radius="$radius" '
{
printf "%54s%8.4f%8.4f\n", substr([=10=],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
假设您的 charge 和 radius 变量不包含反向引用或 /s 或 sed 可能关心的任何其他内容:
$ charge=7
$ radius=2.5
$ sed 's/[^ ]*\( *\)[^ ]*$/'"$charge"''"$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 个字段之间的间距,但扩展了每个字段占用的 space),因此也没有以上解决方案。