【问题标题】:removing a case clause: bash expansion in sed regexp: X='a\.b' ; Y=';;' sed -n '/${X}/,/${Y}/d'删除 case 子句: sed 正则表达式中的 bash 扩展: X='a\.b' ; Y=';;' sed -n '/${X}/,/${Y}/d'
【发布时间】:2010-06-10 10:24:33
【问题描述】:

我正在尝试从 bash 脚本中删除 case 子句。该子句会有所不同,但始终将反斜杠作为大小写匹配字符串的一部分。

我正在尝试 sed,但可以在 bash 脚本中使用 awk 或 perl 单行代码。

编辑的目标很简单,类似于:

 $cat t.sh
 case N in 
 a\.b); 
   #[..etc., varies] 
 ;;
 esac

我正在与转义反斜杠、分号或两者的变量扩展发生冲突。如果我“评估”,我会去掉我的反斜杠转义符。如果我不这样做,分号就会赶上我。所以我尝试在 sed 中进行 subshel​​l 扩展。正如我所写的那样,这会使解释器犯规。更多地转义分号似乎没有帮助。

X='a\.b' ; Y=';;'   
sed -i '/$(echo ${X} | sed -n 's/\\/\\\\/g')/,/$(echo ${Y} | sed -n s/\;/\\;/g')/d t.sh

还有这个:

perl -i.bak -ne 'print unless /${X}/ .. /{$Y}/' t.sh  # which empties t.sh

eval perl -i.bak -ne \'print unless /${X}/ .. /{$Y}/' t.sh  # which does nothing

【问题讨论】:

  • 你的转义斜线在我看来有点倒退(应该是`\`而不是/)。在单引号字符串中,变量无论如何都不会插值,所以你有一些转义是多余的
  • 呃。但这有效(抱歉没有漂亮的打印): $ echo ${X} | sed -e 's/\\/\\\\/g' ; # a\\.b ; $ sed -e '/a\\.b/,/\;\;/d' t.sh ; $cat t.sh ;案例 N 在 ; esac ;这是想要的效果。这个想法是以编程方式而不是像上面那样以交互方式将一个对 shell 友好的字符串放入 sed 中。这就是明显多余的转义符(即 \,“/”用于 sed 定界)出现的地方。

标签: perl bash sed variable-expansion


【解决方案1】:

Bash 的 printf 有一个可以提供帮助的引用功能:

X='a\.b'; Y=';;'
sed "/$(printf "%q" "$X")/,/$(printf "%q" "$Y")/d" t.sh

或者您还可以使用printf 变量赋值功能:

printf -v X "%q" 'a\.b'
printf -v Y "%q" ';;'
sed "/$X/,/$Y/d" t.sh

注意在sed 命令参数周围使用双引号。单引号将防止变量的扩展和命令替换。但是,当不使用这些时,通常最好使用单引号。

【讨论】:

    【解决方案2】:
    X='a\.b'
    Y=';;'
    perl -i.bak -ne 'print unless /\Q'$X'/ .. /\Q'$Y'/' t.sh
    

    这是玩shell引用的游戏,但效果很好。 :)

    【讨论】:

    • 谢谢!我很好奇如何让 bash 服从我的意愿,但我会接受这个并逃跑!
    • 改变我对解决方案的投票。 Perl 可以工作,但 printf 保留在 bash 中。
    猜你喜欢
    • 2013-01-20
    • 1970-01-01
    • 2021-04-25
    • 2012-08-24
    • 2021-11-02
    • 1970-01-01
    • 2019-05-18
    • 2019-01-07
    • 2012-01-28
    相关资源
    最近更新 更多