grep 找到正确的行,sed 更改内容,然后将其放回原始文件?

Joh*_*ard 9 grep sed variable-substitution

我正在尝试更改文件中特定行上的单个单词,但我在将所有连接在一起时遇到了一些问题。

基本上,在我的文件的一行中有一个关键字“firmware_revision”,在这一行(并且只有这一行)我想用“production”这个词替换“test”这个词。

所以我可以这样做:

grep 'firmware_revision' myfile.py | sed 's/test/production'
Run Code Online (Sandbox Code Playgroud)

这将挑选出我想要的行并执行替换,但我无法弄清楚如何将此新行放入原始文件以替换旧行。我显然不能只是将它重定向回文件,那我该怎么办?

即使我使用临时文件,通过使用grep只获取我需要的行,我会丢失文件中的所有其他数据,因此我不能再将其全部重定向到临时文件,然后用临时文件替换原始文件。

编辑 - 有人要求提供更多信息

假设我有一个充满这样行的文件

[
  ('key_name1', str, 'value1', 'Description'),
  ('key_name2', str, 'value2', 'Description'),
  ('key_name3', str, 'value3', 'Description'),
  ('firmware_revision', str, 'my-firmware-name-test', 'Firmware revision name')
]
Run Code Online (Sandbox Code Playgroud)

现在我想编写一个脚本(最好是单行),它将找到包含“firmware_revision”的行,并将该行上“test”一词的所有实例更改为“production”。“测试”这个词可能在那个文件的其他地方,我不希望那些改变。所以要清楚,我想将上面的行更改为

('firmware_revision', str, 'my-firmware-name-production', 'Firmware revision name')

我该怎么做呢?

Joh*_*024 23

尝试:

sed -i.bak '/firmware_revision/ s/test/production/' myfile.py
Run Code Online (Sandbox Code Playgroud)

在这里,/firmware_revision/充当条件。与正则表达式匹配的行为真firmware_revision,其他行为假。如果条件为真,则执行后面的命令。在这种情况下,该命令是一个替换命令,取代的第一次出现testproduction

换句话说,该命令s/test/production/仅在匹配 regex 的行上执行firmware_revision。所有其他线路不变地通过。

默认情况下,sed 将其输出发送到标准输出。但是,您想就地更改文件。所以,我们添加了这个-i选项。特别是,-i.bak使用.bak扩展名保存的备份副本使文件就地更改。

如果您已经确定该命令对您有用,并且您想危险地生活而不创建备份,那么在 GNU sed (Linux) 中,请使用:

sed -i '/firmware_revision/ s/test/production/' myfile.py
Run Code Online (Sandbox Code Playgroud)

相比之下,在 BSD (OSX) 上,该-i选项必须有一个参数。如果您不想保留备份,请为其提供一个空参数。因此,使用:

sed -i '' '/firmware_revision/ s/test/production/' myfile.py
Run Code Online (Sandbox Code Playgroud)

编辑

在对问题的编辑中,OP 要求将行上的每个出现test替换为production. 在这种情况下,我们将g选项添加到用于全局(对于该行)替换的替换命令:

sed -i.bak '/firmware_revision/ s/test/production/g' myfile.py
Run Code Online (Sandbox Code Playgroud)

  • 为了完整起见,您可能还希望解释“-i.bak”部分。 (5认同)
  • @StephenHarris 好点。添加了“-i”的解释。 (5认同)
  • OP 想要 ** 将该行上“测试”一词的所有实例更改为“生产”**。在这种情况下,将 /g 附加到 sed 命令很重要:`sed -i '/firmware_revision/s/test/production/g' myfile.py`,否则只会更改 *first* 实例。 (3认同)