1

I have a bash script that deals with files. It finds all the files in one directory and searches for the name of each in another directory. For that it uses

"${myfiletobesearched}"

inside the script. However if the file name contains [ or ], the script won't find it in the second directory, even if a copy of the file is there as well. What can I do, so that the file names are recognized to be the same?

I was able to narrow the problem down to an example.

myfile="My File [Official Awesome File].txt"
find ./ -name "${myfile}" -type f

does give any output, even if there is a file with that name. To write \[ or something like that is of course not an option, because myfile comes from inspecting a directory.

Here is the script: https://gist.github.com/Make42/5bdae5e4de32cff0d01c9486b09383ee

6
  • 1
    Please show an example of code and inputs that demonstrate the problem. Otherwise we're just guessing Commented May 1, 2016 at 15:39
  • @roaima: I can show the entire script. Where can I do this? Should I post everything into the window or is there a better place to show more code?
    – Make42
    Commented May 1, 2016 at 15:42
  • 1
    I'll try to extract the important part for a minimal working example.
    – Make42
    Commented May 1, 2016 at 15:45
  • @roaima: Added an example.
    – Make42
    Commented May 1, 2016 at 16:08
  • @don_crissti: The script I wrote looks into a first directory from where it takes the names of all the files in it. Then the script searches in a different directory whether it can find files with the same names from the first directory. This works as long the names of the files in the first directory do not have any [ or ] in them. I don't know why - only that my example (see question) does not work either. If I get the example to work, everything should work.
    – Make42
    Commented May 1, 2016 at 16:19

2 Answers 2

1
myfile="My File [Official Awesome File].txt"
myfile=$(echo $myfile | sed -r 's/(\[|\])/\\\1/g')    
find ./ -name "${myfile}" -type f

can you check if this works?

I'm expecting this'll change value of myfile to

myfile="My File \[Official Awesome File\].txt"

Better would be to use printf:

myfile=$(printf '%q\n' "$myfile")

In your specific example within find that would be:

find ./ -name "$(printf '%q\0' "$myfile")" -type f
4
  • Seems to work in my example. However, I just realise that the issue here would be metacharacters in general. So how could I tell find to ignore metacharacters - except $ for this call? Could unix.stackexchange.com/a/141323/122989 be used somehow?
    – Make42
    Commented May 1, 2016 at 16:49
  • yeah, I tried to search some option for that in find command, didn't get any.. so resorted to this hack.. will update if I find any
    – Sundeep
    Commented May 1, 2016 at 16:52
  • Maybe this: unix.stackexchange.com/a/141320/122989
    – Make42
    Commented May 1, 2016 at 16:52
  • myfile=$(printf '%q\n' "$myfile") gives My\ File\ \[Official\ Awesome\ File\].txt
    – Sundeep
    Commented May 1, 2016 at 16:58
0

The argument to find's -name parameter is a glob pattern, not a file name, and square brackets are glob pattern metacharacters.

I found one way around this is to use an in-line perl script which uses an exact-string match instead of a pattern:

myfile="My File [Official Awesome File].txt"
perl -MFile::Find -le 'find( sub {
  return unless $_ eq $ARGV[0];
  print $File::Find::name;
}, $ARGV[1] )' "${myFile}" .

You must log in to answer this question.

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