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

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

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

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

所以我可以这样做:

grep 'firmware_revision' myfile.py | sed 's/test/production'

这将挑选出我想要的行并执行替换,但我不知道如何将此新行放入原始文件中以替换旧行。我显然不能将其重定向回文件,那么我该怎么办?

即使我使用临时文件,通过使用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')
]

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

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

我该怎么做呢?

答案1

尝试:

sed -i.bak '/firmware_revision/ s/test/production/' myfile.py

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

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

默认情况下,sed 将其输出发送到标准输出。然而,您想要就地更改该文件。因此,我们添加了该-i选项。特别是,-i.bak导致文件被更改并保存有扩展名的备份副本.bak

如果您确定该命令适合您,并且您想要危险地生活而不创建备份,那么,使用 GNU sed (Linux),使用:

sed -i '/firmware_revision/ s/test/production/' myfile.py

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

sed -i '' '/firmware_revision/ s/test/production/' myfile.py

编辑

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

sed -i.bak '/firmware_revision/ s/test/production/g' myfile.py

答案2

sed在不支持选项的老式机器上-i

TF=$( mktemp -t "${0##*/}"_$$_XXXXXXXX ) && \
trap 'rm -f "$TF"' EXIT HUP INT QUIT TERM && \
sed '/firmware_revision/ s/test/production/' myfile.py >"$TF" && \
mv -f "$TF" myfile.py

相关内容