我正在尝试更改文件中特定行上的单个单词,但将所有单词连接在一起时遇到一些问题。
基本上,我的文件中的一行有一个关键字“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。如果条件为真,则执行后面的命令。在这种情况下,该命令是一个替代命令,用于替换第一次出现的test
with 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