Bash, find : How to avoid [...] pattern matching in file names expanded from "$var"?
I have two directories, dir1 and dir2. There are about 450 files in each directory. The files in dir2 should have exactly the same names as the files in dir1.
Some of the file names have [...] in them. I can't change the names of the files due to existing naming conventions. My goal is to find files in dir2 with the same name as files in dir1 and execute commands on them. What follows is an abbreviated example of my failure until now. Code:
foo$ ls -R The expansions of $src are as follows. Code:
dir1$ for src in * ; do echo "$src" ; done I want to stop the pattern matching and treat the expansion of "$src" as a literal. How? Edit The reason I want to use find is because some of the files in dir2 are nested in subdirectories which don't exist in dir1. So I'm trying to match files like this: ./dir1/file1 -> ./dir2/subdir1/file1 ./dir1/file2 -> ./dir2/subdir2/file2 ./dir1/file[a1] -> ./dir2/file[a1] There is no way for me to predict in advance whether or not the duplicate file in dir2 is in a subdirectory or how many levels deep it is nested. |
for src in * ; do [ -f "../dir2/$src" ] && echo "$src" ; done
|
Quote:
Sorry I didn't make that clear in my OP :o |
well this uses a find
perl -MFile::Find -e 'map { $files{$_} = $_ } @ARGV; find({ wanted => sub {print "$_\n" if exists $files{$_}}}, "../dir2")' * if you need the full path in ../dir2 then this instead perl -MFile::Find -e 'map { $files{$_} = $_ } @ARGV; find({ wanted => sub {print "$File::Find::name\n" if exists $files{$_}}}, "../dir2")' * |
perl? Are you serious? What did I ever do to you?
:p I'd much rather have a solution I can understand. I'd prefer one which doesn't require me to abandon Bash or Gnu Find. Most importantly, I'd really like to know an answer to the question posed in the OP. Thanks for your replies so far, BTW. I do appreciate it :) |
How about:
Code:
$ set -f |
guess you have no choice but quote-out the glob characters found in filenames. i.e. process your src variable like this one:
Code:
#!/bin/bash |
how about?
Code:
|
Quote:
Having said that (join us), it doesn't require you to abandon bash, using a perl script or one-liner is the same as using find, sed, awk, whatever. You can just run it in a subshell and capture/use the output (really just join us). Code:
#!/bin/bash (see how easy it is to join us) ;) |
bloody perlites taking over the world ... hehe .. jk
|
Sorry, but that's not the problem.
Quote:
4.3.1 The Set Builtin - Bash Reference Manual This doesn't work because the files listed are simply the contents of dir2 (and its subdirectories). The globbing is now being done by find instead of bash. I did a sample run with a unique file name in dir2 to show this. Code:
foo$ ls -R
I want to find files in dir2 (and its subdirectories) with the same names as files in dir1 (with no subdirectories) and then perform commands on them. This doesn't work either. Code:
dir1$ for i in * ; do set -f ; find ../dir2/ -type f -name "$i" ; done ; set +f Thank you for showing me how to disable globbing in Bash though :) |
This works great!
Quote:
3.5.3 Shell Parameter Expansion - Bash Reference Manual Your solution directly addresses the problem as explained in my OP. I have to give you props for reading carefully and understanding my help request even though I should have explained better. :hattip: Code:
foo$ ls -R Code:
dir1$ for src in * ; do src="${src//[/\[}" ; find ../dir2/ -type f -name "${src//]/\]}" -exec echo '{}' \; ; done Code:
dir1$ for src in * ; do find ../dir2/ -type f -name "${src//[/\[}" -exec echo '{}' \; ; done |
This works too!
Quote:
Code:
dir1$ find /tmp/foo/dir2 -type f -exec basename {} \; | while read f; do [ -f "$f" ] && echo $(dirname "$f")/$(basename "$f"); done Code:
dir1$ find /tmp/foo/dir2 -type f | I wonder what the limits or downside might be of piping the output of find into a loop? I'm marking this thread solved now. If anyone else has more interesting or more graceful solutions, then please feel free to add them here. |
That's just crazy talk
Quote:
I wrote a few perl scripts in college. Still have the book in the basement somewhere. Maybe some day I'll dig it out and give it another go. Most likely not, though. :rolleyes: Wonder if the Ruby and Python camps will be chipping in too? |
Well here is something a little more extreme, but will cover more than just []:
Code:
while read -r FILE |
All times are GMT -5. The time now is 04:30 AM. |