bash - 如何在 sed 中使用 shell 通配符?

标签 bash shell sed wildcard glob

我正在尝试在 sed 中使用 shell 通配符。以下失败。 (我希望 foo 作为输出。)

$ touch foo
$ ls
foo
$ echo *
foo
$ bar=*
$ echo $bar
foo
$ echo "$bar"
*
$ echo replace | sed "s/replace/${bar}/"
*
$ echo replace | sed "s/replace/"${bar}"/"
*

正如预期的那样,倒数第二个命令不会生成 foo,因为 ${bar} 被(双)引用。但是,我希望最后一个命令能够扩展通配符。

不过,我可以在执行以下命令后使任一命令正常工作。

bar=$(echo *)

此外,我预计在下面会出现 shell 通配符扩展,但这并没有发生。

$ echo replace | sed s/replace/*/
*

但是,这可行。

$ echo replace | sed s/replace/$(echo *)/
qwe

最佳答案

您的最后一个命令确实尝试扩展通配符,但失败了。来自 man bash:

 Pathname Expansion
        After  word  splitting,  unless  the -f option has been set, bash
        scans each word for the characters *, ?, and [.  If one of these
        characters appears, then the word is regarded as a pattern, and
        replaced with an alphabetically sorted list of file names matching
        the  pattern.

正如它所说,bash 尝试将包含 * 的每个单词扩展为匹配的文件名。在您的情况下,它尝试扩展为以 s/replace/开头的文件名,但没有这样的文件。为了证明这一点:

$ echo "aaaa" | sed "s@a@*@g"
****

$ echo "aaaa" | sed "s@a@"*"@g"
****

$ touch s@a@b@g

$ echo "aaaa" | sed "s@a@*@g"
****

$ echo "aaaa" | sed "s@a@"*"@g"
bbbb

至于解决您的问题,您可以使用评论中提到的子shell扩展。

关于bash - 如何在 sed 中使用 shell 通配符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19476560/

相关文章:

bash - HandBrakeCLI bash 脚本转换文件夹中的所有视频

macos - 如何从 shell 脚本获取文件大小(以字节为单位)?

shell - 执行 shell 脚本时未找到 fc

shell - 将最后一个位置参数分配给变量并将其从 "$@"中删除

Linux wget 文件输出

shell - "Event not found"unix中的shell命令错误

linux - 将 CSV 值导入 Bash

bash - 如何将字符串转换为 Bash 中单个字符的数组?

Bash curl 和 url 中间的变量

node.js - 从父 Node 进程(PM2、NodeJS)运行更新脚本