我有一个我命名的文件poscar1.cif
,我想在此文件的特定行插入变量的内容。
例如,线24
,当前内容为:
_cell_length_a
我想添加变量的内容a
(在我的函数中定义为a=5.3827
)这样该行现在显示为:
_cell_length_a 5.3827
有没有办法使用 sed 或 awk 来做到这一点?我正在使用 bash 脚本来完成此操作(不幸的是,完整的脚本太大,无法发布)。
自从老将ed http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ed.html实用程序不再受到足够的关注:
a=5.3827
ed -s poscar1.cif <<EOF
g/^_cell_length_a\$/ s//& $a/
w
EOF
ed
truly edits a file in place, unlike sed
with its -i
option[1].
sed
借用了很多功能ed
,因此在功能上存在显着的重叠,但也存在重要的差异,其中一些差异在这里体现出来。
-
-s
抑制ed
的状态消息。
-
poscar1.cif
是要就地编辑的输入文件。
-
<<EOF ...
is the 此处文档 http://mywiki.wooledge.org/HereDocument其中包含以下命令ed
- ed
要求其命令来自stdin并且每个命令都独占一行。
-
g/^_cell_length_a\$/
... is a (basic) regex (regular expression) that matches all lines that exactly contain _cell_length_a
- the g
ensures that no error is reported if there's no match at all.
- 请注意,
$
is \
-转义以保护它不被解释shell在此处文档内(并非绝对必要)this实例,但很好的做法)。
-
s//& $a/
... //
repeats the search for the most recently used regex on a matching line and replaces the match with itself (&
), followed by a space and the value of variable $a
.
- 请注意,由于开始分隔符 (
EOF
)此处文档是unquoted, shell变量扩展确实发生;本质上,shell 将这些内容视为双引号字符串的内容。
-
w
writes the modified buffer back to the input file.
- 为了调试,使用
,p
代替w
以便仅print修改后的缓冲区,而不将其写回文件。
[1] 重新就地更新:
更确切地说,ed
保留文件的现有状态inode,这确保了所有文件的属性被保留。
然而,它确实not覆盖现有文件的各个字节,但是读到entire文件存入内存中的缓冲区,并根据要求将整个缓冲区写入文件。
这使得ed
仅适用于足够小的文件作为一个整体读入内存.
相比之下,sed -i
(GNU and BSD sed
), its GNU4.1+对应,awk -i inplace
,并且perl -i
replace原始文件带有新创建的 one,这意味着他们:
-
destroy symlinks(!) - if the input file was a symlink, it is replaced with a regular file of the same name
- 一个重要的常见场景:比如说你的 shell 初始化文件
~/.bashrc
is a symlink到您在源代码控制下保存的其他地方的文件;然后你安装一个使用的工具sed -i
修改~/.bashrc
,这会导致它被替换为常规文件,并且源代码控制版本的链接已损坏。
- 更重要的是,BSD
sed
的行为甚至会带来安全风险(见下文)。
- do not保存原始文件创建日期(如果支持的话;例如,在 OSX 上)
-
they do, 然而,
- 保存扩展属性(如果支持的话;例如,在 OSX 上)
-
保存文件权限
- Caution: BSD
sed
introduces a security risk with respect to symlinks (behavior still present as of the version that comes with FreeBSD 10):
- The symlink的权限被复制到替换文件,而不是符号链接target的。由于符号链接得到可执行文件默认权限,你总是会得到一个可执行文件 file,输入文件是否可执行。
- 幸运的是,GNU
sed
正确处理这种情况。
sed
, gawk
, and perl
could通过采取额外的步骤来解决上述问题,但有只有保留原始索引节点才能确保一件事,如ed
does:
当监视文件的更改时通过其索引节点号(例如,tail -f
),不保留 inode 会破坏监控。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)