如何使用 sed 将 (***) 替换为 \(***\)

如何使用 sed 将 (***) 替换为 \(***\)

所以我想编写一个脚本来用转义的等效字符替换特殊字符,以便我可以将其传递给 mkdir 命令。由于一位朋友使用了类似的行,我可以用它来用下划线替换括号,如下所示:

echo 'Hello (World)' | sed 's/(\|)/_/g'

但是当我将其更改为以下命令时,输出不是我想要的

echo 'Hello (World)' | sed 's/(\|)/\(\|\)/g'

系统输出: Hello (|)World(|)
我想要的输出: Hello \(World\)

有办法做到这一点吗?我使用了其他人的建议,例如使用“tr”命令,但也无法从中获得所需的输出。

答案1

...使用它们的转义等效项,以便我可以将其传递给 mkdir 命令。

根本不要这样做。反而,引用字符串:

name1="Hello (World)!"
name2="I want this to be a five-star directory (*****)"
mkdir -- "${name1}" "${name2}"

要不就

mkdir "Hello (World)"
mkdir "I want this to be a five-star directory (*****)"

简单有效。

答案2

我建议:

1.有点可读的版本

echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g'

每次调用都针对一种括号。 “查找”部分只是查找括号,而替换部分则将相同的括号放回原处,但在反斜杠之后,我们需要对其进行转义。

2. 紧凑型

这也将起作用:

echo 'Hello (World)' | sed -E 's/(\(|\))/\\\1/g'

这里我们只调用 sed 一次。

告诉-Esed 使用扩展正则表达式在括号和特殊字符方面表现不同(并且更“现代”)。这允许我们使用捕获组。

在“查找”部分,我们告诉 sed 查找左括号或右括号。他们逃脱了。整个“( 或 )”组本身括在括号中,括号不会转义,因为它们用于告诉 sed 记住在该组中找到的内容。然后在替换部分中,我们放置反斜杠(像以前一样转义),以及 sed 之前找到的任何内容,称为\1.

3. 将其链接到 mkdir

问题的核心是通过 sed 实现提供的输出。至于OP简要提到的初衷,这种方法有点做作,但可行。对于名为“Hello (World)”的目录,这可以工作:

echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g' | sed 's/ /\\ /g' | xargs mkdir

我们还需要逃离这个空间,就像以前一样。 Xargs 用于将上一个命令的输出传递给 mkdir。或者:

echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g' | xargs -I{} mkdir '{}'

这可以通过将先前的输出括在引号之间来避免空格的转义(最好不要在所需名称中包含引号!)

如前所述,这是相当人为的,关于使用 mkdir 而简单地将名称括在引号中的另一个答案可能是OP的方法。

相关内容