使用 `find` 查找文件名,带

使用 `find` 查找文件名,带

背景:我试图查找 xml 文件中提到的音乐文件来组织我的音乐播放列表。我正在编写一个脚本,从 xml 标记中提取文件名以自动查找文件。

我的音乐位于$musicroot,因此我find在那里发布。但由于字符问题,我找不到以下文件[]

find $musicroot -name "R. Kelly - Step In The Name Of Love [mp3clan.com].mp3" -type f

没有返回任何内容,但如果我退出,[]它就会起作用。

find $musicroot -name "R. Kelly - Step In The Name Of Love \[mp3clan.com\].mp3" -type f
/mnt/Data/Dynamic/Multimedia/Music/Not Desi/Party/R. Kelly - Step In The Name Of Love [mp3clan.com].mp3

请注意,在我的脚本中,歌曲文件在歌曲循环中迭代并存在于变量中$song。不确定这是否有区别。

我真的很想能够直接将文件名传入我的脚本中,而不必担心像这样的转义字符,但我似乎无法在网上找到任何相关信息。可能是因为find 是一个很常见的英语单词,find很难搜索。find

这可能吗?

答案1

如果您只是在寻找这个文件,那么只使用 bash 就可以完成:

shopt -s globstar
printf "%s\n" "$musicroot"/**/"R. Kelly - Step In The Name Of Love [mp3clan.com].mp3"

在 bash 中,globstar允许使用**递归通配符。当然,一旦文件名被引号括起来,bash 就不会再对其进行通配符扩展(因此,您$musicroot也应该将其括起来)。

答案2

bash shell 的printf内置命令有一个%q格式说明符,

      %q     causes  printf  to output the corresponding argument in a
             format that can be reused as shell input.

从文档中无法完全清楚“重用为 shell 输入”的具体含义,但是它至少转义了命令find参数中特殊的空格和通常的文件名生成(glob)字符-name

$ x="fo*o [ba?r]"
$ printf '%q\n' "$x"
fo\*o\ \[ba\?r\]

所以你可以尝试

song="R. Kelly - Step In The Name Of Love [mp3clan.com].mp3"
find dir -name "$(printf '%q' "$song")"

请注意,如果您有 zsh,您可以使用其q参数扩展标志更直接地执行相同操作:

 ~ % song="R. Kelly - Step In The Name Of Love [mp3clan.com].mp3"
 ~ % find dir -name $song:q
dir/bar/R. Kelly - Step In The Name Of Love [mp3clan.com].mp3

(bash shell 具有表面上类似的@Q扩展标志,但是其操作方式不同 - 本质上只是硬引用整个字符串。)

答案3

grep有一个--fixed-strings选项可以做你想做的事,你可以将它与以下选项一起使用find

find $musicroot -type f | grep --fixed-strings "R. Kelly - Step In The Name Of Love [mp3clan.com].mp3"

答案4

也许用这个命令来解析文件名tr

$ tr '[]' '*' <<< "$var"
R. Kelly - Step In The Name Of Love *mp3clan.com*.mp3

相关内容