For loop with space in file name

Hi All

I have a source file named

ABC-20150613 to 20150613.zip

. I was trying to execute the below command on this source file, but its telling file is not available in that path and giving me some random file names.

ls -ltr| for z in ABC-????????*to*????????*.zip
do unzip $z -d
done

I want the file name to check by using full pattern, which makes me to give question mark. Kindly help me on this

would

ls -ltr| for z in "ABC-????????*to*????????*".zip
do unzip $z -d
done

not do the job?

I think the for loop's arguments should be expanded.
But the command argument must not be expanded again.
Also, the ls output seems pointless (if nothing in the loop reads from stdin).

for z in ABC-????????*to*????????*.zip
do unzip "$z" -d
done

The pipe feeding the loop does nothing useful because the filenames are picked by matching the pattern you give after in with the content of your current directory.
Arguments for commands and programs are usually seperated by spaces. Your initial attempt fails because unzip treats every part of the filename that is seperated by space as a filename. You have to quote the variable representing the filename to tell unzip , that it is indeed a single filename:

for z in ABC-????????*to*????????*.zip
do unzip "$z" -d
done

PS.: typing half of the reply, then going to lunch and submitting thereafter is not the best idea :rolleyes:

1 Like

I agree with MadeInGermany with one caveat: You are being precise with the number of characters in the date segments of the filename, and then blowing it with the spaces. Your pattern would match this:

ABC-1234567890to0987654321.zip

This would be better:

for z in ABC-????????\ to\ ????????.zip
do unzip "$z" -d
done

Andrew

1 Like

Maybe I'm being thick, but what is the ls -lrt | for? I don't see it having any purpose the way it is coded. You need to quote $z when you use it to preserve the whitespace too.

If you want to get the files matching the pattern in modified date order (oldest first) then would you be better with something more like this?:-

for z in $(ls -1rt | grep -E "^ABC-.{8,}to.{8,}\.zip$")
do
   unzip "$z" -d
done

Note that I have used a digit 1 not a letter l else you get all sorts of other details you will not want.

To match your original specification, the extended expression for the grep should read:-

  • Starts with ABC-
  • Eight or more other characters (take out the comma in the {8,} to make it exactly 8)
  • Literal to
  • Eight or more other characters
  • And ends with the literal .zip (escaped dot)

If the filename length is fixed as describing something like a date with spaces in the name, then perhaps this would be neater all round:-

for z in ABC-????????\ to\ ????????.zip
do
   unzip "$z" -d
done

It depends what you will accept as input and whether the modification time of the file or the name of the file should be used for sorting.

Do either of these help?

Robin

2 Likes