使用 sed 同时删除和添加

使用 sed 同时删除和添加

我的脚本中有一个我想更改的变量:

read -p "Enter the name of city: " city
if [[ $city =~ Liverpool ]]; then
    sed -i -e "/\$type\_of\_city =/ s/= .*/= ${city}/" /cities  
    echo -e "Liverpool: `grep '$name_of_city' cities"
fi

在城市文件中有一个#我想删除的变量:

#$type_of_city = something

所以我想同时更改somethingLiverpool实际上适用于上面的代码,但我不知道如何删除该#标志。

现在我明白了#$type_of_city = Liverpool,但我想看看$type_of_city = Liverpool

答案1

稍微修正一下代码块,

read -p "Enter the name of city: " city
if [ "$city" = 'Liverpool' ]
then
    sed -Ei 's/^#* *(\$type_of_city) *= *.*/\1 = '"$city"'/' cities  
    printf "%s: %s\n" "$city" "$(grep -F "$city" cities)"
fi

在这里,我们将该行与扩展 RE 相匹配^#* *(\$type_of_city) *= *.*。分解它代表:

  • ^- 行的开头
  • #*- 零个或多个#字符
  • *- 零个或多个空格
  • ()- 封闭块上的匹配,稍后用作\1
  • \$type_of_city- 文字字符串$type_of_city\$经过转义以防止与行尾错误匹配)
  • *- 零个或多个空格
  • =- 文字字符
  • *- 零个或多个空格
  • .*- 零个或多个任意字符

如果匹配成功,我们将该行重写为\1 = $city,其中\1是括号中的()ERE 匹配的值,$city是变量的值。

请注意,我们将变量的值$city直接放入sed替换字符串中,因此如果它包含诸如 的字符/或诸如 的序列,\1它将产生(最多)意外的结果,甚至导致sed失败。在当前代码中,这是通过if要求输入值为 的子句进行保护的Liverpool,但如果您要删除该子句或过于放松它,则可能会遇到此问题。

答案2

在您的情况下,我会将整行替换为sed,其中#被锚定为行开头之后的可选字符:

sed "s/^#\{0,1\}\$type_of_city =.*/type_of_city = $city/" /cities

这将取代

  • #紧随该行开头 ( ) 之后出现 0 或 1 次^,后跟
  • 文字字符串$type_of_city =,后跟
  • 任意文本直到行尾

$type_of_city =,后跟内容多变的$city

您使用的地址说明符不是必需的,因为只有在搜索模式匹配时才会执行替换。

笔记由于您$city从用户输入中获取,因此您应该确保在使用之前验证/清理输入;否则你将打开你的脚本代码注入漏洞如果用户sed在输入中包含命令语法。

正如 Stéphane Chazelas 在评论中指出的那样,您可以通过使用perl而不是通过环境或作为参数sed传递值的位置来避免这种情况,而不是将其嵌入到代码中。$citysed

相关内容