With my limited knowledge of Linux tools, I hit a wall. Because my list of files contains spaces (space character), the "find" command fails to find any hits, but does not produce any errors. The reason for this script is to help with (re)transcoding of previously already transcoded files, such as music or movies.



while read line; do

echo "# $n : $line"

find ${searchDir} -iname "$FILES.*" -type f


done < $filename

I'm not sure where to go from here as awk or sed examples I found rarely deal with processing variables.

The input file would contain filenames in the form of:

Supertramp [The Very Best Of Supertramp] -05- Breakfast In America.m4a
Supertramp [The Very Best Of Supertramp] -07- Take The Long Way Home.m4a
Supertramp [The Very Best Of Supertramp] -09- Dreamer.m4a

Not quote delimited, and no paths.

The output of the script would be the path and filename that best matches the above list. Note that the source files and results have different file extensions:

/volume2/music/Supertramp/1990. The Very Best Of Supertramp/Supertramp [The Very Best Of Supertramp] -05- Breakfast In America.flac
/volume2/music/Supertramp/1990. The Very Best Of Supertramp/Supertramp [The Very Best Of Supertramp] -07- Take The Long Way Home.flac
/volume2/music/Supertramp/1990. The Very Best Of Supertramp/Supertramp [The Very Best Of Supertramp] -09- Dreamer.flac
  • Please explain how "the find command fails". Error message? Unexpected output? No output? Mar 31, 2023 at 17:38
  • The file that contains spaces - is that filenames contain spaces, or the file contains blank lines (with or without spaces on them)? Mar 31, 2023 at 17:39
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Mar 31, 2023 at 18:08
  • 2
    The issue is likely not the spaces (which are properly handled by your quoting of the expansion "$FILES.*") but the [ and ] characters Mar 31, 2023 at 18:08
  • 1
    ... see for example Find fails if filename contains brackets Mar 31, 2023 at 18:11

1 Answer 1


With the zsh shell:

set -o extendedglob

names=( ${(f)"$(<$filename)"} )
files=( $searchdir/**/(#i)(${(~j[|])names:r}).*(ND.) )
print -rC1 -- $files

In addition to case insensitive matching enabled with (#i) here, you can also enable approximate matching. For instance (#a2) allowing matches with up to 2 errors (omissions, insertions, transposition, different character).

  • $(<file) expands to the contents of the file. Here it's quoted to prevent IFS-spitting.
  • ${(f)expansion} splits the expansion on line feeds.
  • ${file:r} expands to the rootname of the file (extension removed). When applied to an array, that applies to all the elements.
  • ${(j[|])array} joins the array elements with |. With ~, that | is treated as a glob operator (alternation).
  • **/ matches any level of subdirectories (including 0).
  • (ND.): glob qualifiers:
  • Nullglob: no error if there's no match
  • Dotglob: also look for hidden files
  • . matches only regular files (like the -type f of find).
  • So, to clarify in my own mind, ${(~j[|])names:r} treats | as an (extended) glob operator because of the ~ flag, but does not treat [ and ] specially in the expansion of names because unquoted variable expansions are not subject to split+glob by default? Mar 31, 2023 at 23:44
  • @steeldriver, yes ${(~j[string])array} applies globsubst to that join string only, while $~var applies globsubst to the whole expansion (and $=var does splitting so $~=var in zsh is like the $var of sh, something you almost never want). Apr 1, 2023 at 7:54
  • Thank you Stéphane. Unfortunately, I should have also stated that this will be running on a NAS (Synology) for which I only have access to BASH. At least, by default. Apr 2, 2023 at 14:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .