【问题标题】:Replacing a word containing backslash(\) with sed用 sed 替换包含反斜杠(\)的单词
【发布时间】:2018-05-09 22:55:30
【问题描述】:

我想用包含 .ly 文件的文件夹中的其他字符串替换一些字符串(.ly 文件是用于编写音乐的文件,然后可以将其转换为 svg 文件)。一个问题是文件包含反斜杠 (\)。

无论如何,我想做的是替换以下字符串:

\f  with \fffff 
\p  with \ppppp
mordent  with reverseturn 
r4  with \mordent 

我要替换的每个字符串(以及要替换的每个字符串)最后都有一个空格。这是因为我不想要像

这样的字符串
\pt to be replaced with \pppppt

同样,因为反斜杠很重要,像

这样的字符串
\ff should stay the same (only f with a slash before and a space after should be replaced).

我用来实现这一点的代码是:

for f in *.ly
do 
    filename="${f}"
    sed -i -- "s@\p @\ppppp @g; s@\f @\fffff @g; s@mordent @reverseturn @g; s@r4 @\maxima @g" $filename;

done

我正在使用分隔 @ 而不是反斜杠来实现这​​一点。

但是,该程序给出了一些完全奇怪的行为。特别是:

\f  stays the same (wrong behavior, the right behavior is to get transformed to \fffff)
\p  is converted to \ppppp (correct behavior)
\stemUp  is converted to \stemUppppp (wrong behavior, the right behavior is to remain as it was)

这让我感到困惑,让我头疼。特别是,考虑到它是完全相同的代码,为什么它适用于 \p 但不适用于 \f 。

作为参考,我附加了一个文件 beforeafter 应用 sed 命令。

提前感谢您的帮助!

注意:我使用的是 Ubuntu 16.04 和 sed (GNU 4.2.2)。

【问题讨论】:

  • 您可能需要正确转义双引号内的 \。我建议对sed 程序使用单引号,即's@\p @\ppppp@g;…',而不是你需要在sed 中转义\ 的特殊含义,即's@\\p @\\ppppp@g;…'
  • \f\p 行为不同,因为 \f 被解释为“formfeed”,而 \p 只是变成 p。您必须转义反斜杠才能按字面意思解释(也在单引号内,因为它是 sed 解释字符串)。在你的输入中使用一个普通的p,你会发现当你只使用\p而不是\\p时它也被替换了。
  • 谢谢,现在一切都清楚了。

标签: bash shell sed


【解决方案1】:
$ echo '12p3 p \p foo' | sed 's/\p /\ppppp /g'
12p3 ppppp \ppppp foo
$ echo '12p3 p \p foo' | sed 's/\\p /\\ppppp /g'
12p3 p \ppppp foo

【讨论】:

  • 谢谢!我知道这项工作,但是我仍然不明白为什么它以前对 \p 有效,但对 \f 无效。我猜是量子力学。
  • 我重现了您的相同问题并得到了相同的结果,双引号以 sed 和反斜杠的挑剔方式工作,不惜一切代价避免。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-29
  • 2017-02-08
  • 2023-03-20
  • 1970-01-01
  • 2012-06-16
  • 2011-12-13
  • 1970-01-01
相关资源
最近更新 更多