我有一个包含多行的文本文件。其中一行是:
fixed_stringA = 123, fixed_stringB = 456
我有第二个文本文件(同样有很多行)。这两行按此顺序位于文件中间:
found_value1=unknown1
found_value2=unknown2
我的目标是修改第二个文本文件中的这两行,以便它现在显示为:
found_value1=123
found_value2=456
我的目标是在命令行上执行此操作而不调用另一个脚本。以下代码有效,但我想知道是否可以缩短或改进它:
value_variable=$(grep "fixed_stringA = [0-9]*, fixed_stringB = [0-9]*" first_file \
| sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/\1,\2/'); \
value1=$(echo $value_variable | cut -d "," -f 1); \
value2=$(echo $value_variable | cut -d "," -f 2); \
sed -i -E "s/unknown1/$value1/" second_file.txt; \
sed -i -E "s/unknown2/$value2/" second_file.txt
答案1
我可以把它归结为这两行:
values="$(sed -n -E 's/^.*fixed_stringA\s*=\s*([0-9]+)\s*,\s*fixed_stringB\s*=\s*([0-9]+).*$/\1,\2/p' first_file)"
sed -i -E -e "s/unknown1/${values%,*}/" -e "s/unknown2/${values#*,}/" second_file.txt
第一行使用带有-n
标志的 sed,因此它会抑制常规输出,它会找到目标行,将数值提取到捕获组中\1
,\2
然后将它们转换123,456
为单独打印并保存到变量$values
。
下一行在 中进行两次替换: forsecond_file.txt
中逗号之前的所有内容和 for 中逗号之后的所有内容。$values
unknown1
unknown2
但我确信 awk 导出随时都会带有一句台词。
答案2
根据经验,使用grep
withsed
几乎总是多余的,因为sed
可以自行过滤。在您的情况下,您可以使用p
该命令的标志s
仅在匹配时打印,然后d
elete 抑制正常输出:
sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/\1,\2/p;d' first_file
接下来,您通常会将替换字符串存储在保留空间中,以便将它们应用到第二个文件上,但这不适用于-i
nsplace 编辑,因此我们需要第二个sed
命令。让我们使用第一个脚本为第二个脚本生成脚本:
sed -i.bak $(sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/s_unknown1_\1_;s_unknown2_\2_/p;d' first_file) second_file
内部脚本将产生输出s_unknown1_123_;s_unknown2_456_
,这是第二个文件所需的脚本。
注意:我习惯于-i.bak
与其他版本兼容sed
,并保留一份副本,以防弄乱源文件。