获取一行中最后一个斜杠之前的部分

获取一行中最后一个斜杠之前的部分

我正在尝试编写一个 conky 脚本来显示我的 MPD 专辑封面,即专辑文件夹中的“folder.jpg”。我当前的计划是使用mpc -f %file%,它打印出文件名和路径,然后剪切出实际的文件名(即最后一个 / 之后的所有内容),并将其用作 conky 的图像对象的路径。

我在使用 grep/cut 时遇到问题,特别是因为有些歌曲嵌套在两个文件夹中,而其他歌曲则嵌套在一个文件夹中。 (grep -m 1 . |cut -f1 -d /适用于单文件夹专辑)

我该怎么办呢?我缺少更简单的方法吗?

答案1

您可以使用sed删除其余的 -一切都从最后一个斜杠开始:

mpc -f %file% | head -1 | sed 's:/[^/]*$::'

该模式/[^/]*$匹配斜杠,后跟除斜杠之外的任何字符,直到行尾。它被空字符串替换。
忽略head -1我们想要的行后面的一些状态输出 - 但请参阅下面的内容了解如何首先不将它们打印出来。

如果您不习惯 sed,该命令可能会因为:使用的原因而看起来不寻常。您之前可能见过sed带有 as 分隔符的命令/,例如's/foo/bar/'- 我更喜欢使用分隔符:以提高可读性,因为表达式包含/其自身。或者,我们可以转义/表达式中的's/\/[^\/]*$//'- ,但这不会使其更具可读性。


您使用它的方式为mpc您提供了两个额外的状态行。安静选项-q会关闭所有输出。您需要结合-q显式打印当前播放文件来获取所需的行,仅此而已:

mpc -q -f %file% current | sed 's:/[^/]*$::'

而不是删除一切都从最后一个斜杠开始,可以明确打印最后一个斜杠之前的所有内容:

mpc -q -f %file% current | sed 's:^\(.*\)/.*$:\1:'

匹配后面跟着 a/和任何其他字符的任何字符;尽可能匹配,这样/匹配到的就是最后一个。

答案2

如果您想将此规则应用于单个字符串,则sed可以使用以下命令而不是(请参阅其他答案)dirname

$ dirname "1 2/3 4/5 6/file"
1 2/3 4/5 6

答案3

Grep 并不是完成这项工作的最后一个工具。grep -m 1 .打印第一个非空行,这没有用。您可以构建涉及 grep 和其他工具的复杂解决方案,但最简单的方法是使用sed。一种方法是用空字符串替换最后运行的非斜杠字符以及前面的斜杠:

mpc -f %file% | sed 's:/[^/]*$::'

或者,将所有内容保留到最后一个斜杠并丢弃以下内容:

mpc -f %file% | sed 's:^\(.*\)\(/.*\)$:\1:'

请注意,如果输入不包含/,即如果传递不带目录指示的文件名,这两种方法都会使输入保持不变。如果这是一个问题,您可以在 sed 中解决这个问题,但调用dirname命令:

dirname -- "$(mpc -f %file%)"

在 shell 脚本中,您还可以使用参数扩展构造,但如果您只想打印结果,这会更复杂:

full_path="$(mpc -f %file%)"
case "$full_path" in
  */*) directory_part="${full_path%/*}"
  *) directory_part="."
printf '%s\n' "$directory_part"

相关内容