在特定行的末尾使用Awk或SED在声明上进行钉住

  • 本文关键字:声明 SED Awk bash awk sed
  • 更新时间 :
  • 英文 :


我有一个我叫 poscar1.cif的文件,我想在此文件中的特定行中插入变量的内容。

例如,Line 24,当前读取:

_cell_length_a

我想处理我的变量a的内容(在我的功能中定义为a=5.3827),所以这样的行现在读取:

_cell_length_a 5.3827

有没有办法使用SED或尴尬做到这一点?我正在使用bash脚本来完成此操作(不幸的是,完整的脚本太大而无法发布)。

由于资深人士 ED 实用程序不再引起足够的关注:

a=5.3827
ed -s poscar1.cif <<EOF 
g/^_cell_length_a$/ s//& $a/
w
EOF

ed真正编辑文件在适当的位置,与 sed不同的 -i选项 [1]

seded借了许多功能,因此功能有很大的重叠,但也存在重要差异,其中一些表面表面。

  • -s抑制ed的状态消息。
  • poscar1.cif是要编辑的输入文件。
  • <<EOF ...是此处包含ed -ed命令的文档,其命令要求其命令来自 stdin ,并且每个命令都在自己的行上。
  • g/^_cell_length_a$/ ...是(基本)正则表达式(正则表达式),它匹配所有完全包含_cell_length_a的行 - g可确保如果完全没有匹配,则不会报告任何错误。
    • 请注意,$ -ESCCT,可保护它免受此处遗传中的 shell 的解释(在 this 实例中并不是必需的,但是很好的做法)。
  • s//& $a/ ... //在匹配线上重复对最近使用的正则搜索,并用自身替换比赛(&),然后是一个空间和变量$a的值。
    • 请注意,由于此处的开放定界符(EOF)是 noceed shell shell 可变扩展确实发生了;本质上,壳体像双引号的字符串一样对其进行处理。
  • w将修改后的缓冲区写回输入文件。
    • 要调试,请使用,p代替w,以便仅 print 未经其写回文件而无需。

[1] RE入境更新:

更准确地说, ed保留了文件的现有 inode ,可确保保留所有文件的属性。
但是,它确实不是覆盖现有文件的单个字节,但是将整个 thother 文件读取到存储器中的一个缓冲区中,并写入整个缓冲区当被要求时到文件。
这使 ed仅适用于小的文件,足以将整体读取到存储器中

相比之下, sed -i gnu bsd sed),其 gnu 4.1 对应物, awk -i inplace ,以及 perl -i 替换 new>新创建一个一个,这意味着这意味着他们:

  • 销毁Symlink(!) - 如果输入文件为a symlink ,它是替换为同名的常规文件
    • 重要的情况很重要:说您的外壳初始化文件 ~/.bashrc是a symlink 对您在源控制下保留的文件的 symlink ;然后,您安装了使用sed -i修改~/.bashrc的工具,该工具将其替换为常规文件,并且链接到您的源控制版本。
    • 更重要的是,BSD sed的行为甚至引入了安全风险(见下文)。
  • do 不是保留原始文件创建日期(在支持的情况下;例如,在OSX上)
  • 他们 do ,但是,

    • Preserve 扩展属性(在支持的情况下;例如,在OSX上)
    • 保存文件权限

      • 注意: BSD sed symlinks 介绍A 安全风险:
        • symlink 的权限被复制到替换文件,而不是symlink target 。由于symlinks get 可执行文件默认情况下,>您总是会以可执行文件 file file 最终结束,无论输入文件是否可执行。<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</li>
      • 幸运的是, gnu sed正确处理此情况。

sedgawkperl 可以通过采取额外的步骤来解决上述问题,但是只有在保留原始Inode时才可以确保一件事,就像ed一样,可以确保strong>:

当文件被监视为更改的文件通过其Inode号码(例如,使用tail -f),而不是保留监视的Inode中断。

您可以使用SED来做到这一点,具体取决于您对Dawg问题的回答

sed -i -e '24s/$/5.3827/' poscar1.cif

或者是模式

sed -i -e '/_cell_length_a/s/$/5.3827/' poscar1.cif

第一个使用给定的数字进入线路,以后将应用于与第一组斜线中模式匹配的任何行。无论哪种情况,它都将用最后两个斜线之间的值"替换"线的末端。

使用示例,您可以做类似的事情:

sed -i 's/(_cell_length_a)/1 5.3827/' poscar1.cif

在哪里,

  • -i选项说要编辑到适当的文件,而不是创建副本
  • 时髦的引用部分是一个字符串,指定正则表达式aka正则
  • poscar1.cif是文件

很难阅读正则语法。查找和替换的基本格式是:

s/find/replace/

其中 find是您要寻找的行的文本,而 replace是替换该文本的文本。

如果我们想在替换中使用一部分查找字符串,则通过将其与()一起对其进行分组,然后使用1在替换字符串中参考它。以下附加物替换为包括查找的任何行:

s/(find)/1replace/

请记住,如果您的字符串包含它们,则需要特别处理特殊的逃生字符或元字符。

相关内容

  • 没有找到相关文章

最新更新