sed/awk-通过一个字符串查找匹配项并在同一行上更改不同的字符串

sed/awk-通过一个字符串查找匹配项并在同一行上更改不同的字符串

对于大多数人来说,这应该是一个简单的问题,但对我来说却并非如此。

我需要在 json yml 配置文件上方执行一些文本操作,其中包含一些通道的定义 - 除了变量之外,每行的结构都是相同的。

对我最有帮助的是弄清楚什么是最好的方式

1)在每行上使用带有特定编号的文件,在大配置文件中指定行 2)之后,选中此行并 a)从原始行中删除它(我知道:) b)选中此行,在其中找到另一个字符串并进行更改 - 始终进行相同的更改,如 foo -> bar。并在原始文件中进行更改 - 保留更改后的行的位置。

我的问题是第 2b 部分...对此不太确定,而且我听说 sed 在 yml 或 json 方面有问题,到目前为止我还在使用 vim 来更改字符串等,但现在它更具体了 - 找到行,然后更改特定的字符串。

如果你能给我一些建议,或者我可以阅读/观看什么来正确理解我需要的工具,以便我能够自己解决问题,我将不胜感激

- {channel_id: 483, stream_profile_code: profile1, source_id: igst0-iva, source_domain: }
- {channel_id: 483, stream_profile_code: profile2, source_id: igst0-iva, source_domain: }
- {channel_id: 483, stream_profile_code: profile3, source_id: igst0-iva, source_domain: }
- {channel_id: 483, stream_profile_code: profile4, source_id: igst0-iva, source_domain: }
- {channel_id: 483, stream_profile_code: profile5, source_id: igst0-iva, source_domain: }
- {channel_id: 499, stream_profile_code: profile1, source_id: igst0-iva, source_domain: }
- {channel_id: 499, stream_profile_code: profile2, source_id: igst0-iva, source_domain: }
- {channel_id: 499, stream_profile_code: profile3, source_id: igst0-iva, source_domain: }
- {channel_id: 499, stream_profile_code: profile4, source_id: igst0-iva, source_domain: }
- {channel_id: 499, stream_profile_code: profile5, source_id: igst0-iva, source_domain: }
- {channel_id: 501, stream_profile_code: profile1, source_id: igst0-iva, source_domain: }
- {channel_id: 501, stream_profile_code: profile2, source_id: igst0-iva, source_domain: }
- {channel_id: 501, stream_profile_code: profile3, source_id: igst0-iva, source_domain: }
- {channel_id: 501, stream_profile_code: profile4, source_id: igst0-iva, source_domain: }
- {channel_id: 501, stream_profile_code: profile5, source_id: igst0-iva, source_domain: }

这里我只需要找到包含 channel_id 499 的每一行,并将 igst0-iva 更改为 igst1-ven。我需要查找的通道 ID 列表位于我已准备好的外部文件中。这是一个小例子,我需要从总共 200 个 ID 中更改大约 30 个。

答案1

当然,你可以用一行代码解决问题,但它不可重复使用。所以我建议尝试使用这个快速编写的脚本,并尝试弄清楚它的作用,以提高你的技能。

#!/bin/sh

channel_id="499"
old_source_id="igst0-iva"
new_source_id="igst1-ven"

if [ $# -ne 2 ]; then
    echo "usage: ${0} INPUT-FILE OUTPUT-FILE"
    exit 1
fi

if [ ! -f ${1} ]; then
    echo "file ${1} does't exist"
    exit 1
fi

sed -E "s/(.*channel_id: ${channel_id}.*source_id: )(${old_source_id})(.*)/\1${new_source_id}\3/g;" ${1} > ${2}

exit $?

答案2

我的问题的答案最终当然已经在这里了

原始帖子

sed -i '/STRING—TO-FIND-LINE/s/REPLACETHIS/FORTHIS/' myFile

升级不多

while read id-FIND-LINE; do sed -i "/$id-FIND-LINE/s/REPLACETHIS/WITHTHIS/"  myFile; done < fileWithIDs

相关内容