Prev: how to find and omit a directory containing a file entirely
Next: Directory exclusion from the output of 'echo **'
From: Guillaume Dargaud on 14 May 2010 04:06 Hello all, I would like some way to escape file names I get from something like that: (this is bash syntax) # Get the 10th file in the archive Image=$( zipinfo -1 "$1" | head -10 | tail -1 ) unzip -p "$1" "$Image" | pipe it somewhere The problem is that is $Image contains one of [ ] { } ( ) < > ' " \, etc Then the 2nd line fails Would using something like | sed -e "s/([\[\]\{\}\(\)\<\>\'\"])/\\\1/g" at the end of the 1st line help ? -- Guillaume Dargaud http://www.gdargaud.net/
From: pk on 14 May 2010 06:16 Guillaume Dargaud wrote: > Hello all, > I would like some way to escape file names I get from something like that: > (this is bash syntax) > > # Get the 10th file in the archive > Image=$( zipinfo -1 "$1" | head -10 | tail -1 ) > unzip -p "$1" "$Image" | pipe it somewhere > > The problem is that is $Image contains one of [ ] { } ( ) < > ' " \, etc > Then the 2nd line fails According to the man page, unzip uses the same wildcard characters as the shell: "*", "?" and "[...]", so those are the only characters that need to be escaped. With bash, you can use printf "%q" to correctly escape a filename the way the shell would: $ image='myfile[]with?funny*chars.txt' $ printf "%q\n" "$image" myfile\[\]with\?funny\*chars.txt $ image=$(printf "%q" "$image") $ unzip myzip.zip "$image" Archive: myzip.zip extracting: myfile[]with?funny*chars.txt That should be enough for your situation. If not, please provide a real example of names that don't actually work.
From: Guillaume Dargaud on 14 May 2010 15:44 > With bash, you can use printf "%q" to correctly escape a filename the way > the shell would: Thanks, I didn't know that. I'll give it a shot next week when I get back. -- Guillaume Dargaud http://www.gdargaud.net/
From: Guillaume Dargaud on 18 May 2010 03:50 > According to the man page, unzip uses the same wildcard characters as the > shell: "*", "?" and "[...]", so those are the only characters that need to > be escaped. > > With bash, you can use printf "%q" to correctly escape a filename the way > the shell would: > > $ image='myfile[]with?funny*chars.txt' > $ printf "%q\n" "$image" > myfile\[\]with\?funny\*chars.txt > > $ image=$(printf "%q" "$image") > $ unzip myzip.zip "$image" > Archive: myzip.zip > extracting: myfile[]with?funny*chars.txt > > That should be enough for your situation. If not, please provide a real > example of names that don't actually work. OK, sample file: $ touch "my\$fil��� [1] with ? funny\'s * char.txt" $ zip test.zip * adding: my$fil��� [1] with ? funny\'s * char.txt (stored 0%) $ Image=$( zipinfo -1 test.zip ) $ echo "$Image" my$fil?????? [1] with ? funny\'s * char.txt $ unzip test.zip "$Image" Archive: test.zip caution: filename not matched: my$fil?????? [1] with ? funny\'s * char.txt OK, so I'll use printf... But something will wrong with accents... $ printf -v q "%q" "$(zipinfo -1 test.zip)" $ echo $q my\$fil\?\?\?\?\?\?\ \[1\]\ with\ \?\ funny\\\'s\ \*\ char.txt $ unzip test.zip "$q" Archive: test.zip caution: filename not matched: my\$fil\?\?\?\?\?\?\ \[1\]\ with\ \?\ funny\\\'s\ \*\ char.txt Verification: $ unzip test.zip Archive: test.zip extracting: my$fil?????? [1] with ? funny\'s * char.txt $ ls my$fil��� [1] with ? funny\'s * char.txt test.zip It works if you don't specify a file name... but that's what I want to do... Maybe it's a purely zip problem, but I think I have the same problem with unrar. -- Guillaume Dargaud http://www.gdargaud.net/
From: pk on 18 May 2010 06:30
Guillaume Dargaud wrote: >> According to the man page, unzip uses the same wildcard characters as the >> shell: "*", "?" and "[...]", so those are the only characters that need >> to be escaped. >> >> With bash, you can use printf "%q" to correctly escape a filename the way >> the shell would: >> >> $ image='myfile[]with?funny*chars.txt' >> $ printf "%q\n" "$image" >> myfile\[\]with\?funny\*chars.txt >> >> $ image=$(printf "%q" "$image") >> $ unzip myzip.zip "$image" >> Archive: myzip.zip >> extracting: myfile[]with?funny*chars.txt >> >> That should be enough for your situation. If not, please provide a real >> example of names that don't actually work. > > OK, sample file: > $ touch "my\$fil��� [1] with ? funny\'s * char.txt" > $ zip test.zip * > adding: my$fil��� [1] with ? funny\'s * char.txt (stored 0%) > > $ Image=$( zipinfo -1 test.zip ) > $ echo "$Image" > my$fil?????? [1] with ? funny\'s * char.txt Here is the problem (I can reproduce it on my system as well). It seems that unzip and zipinfo do not show multibyte characters in file names correctly. Once the file is added to the zip archive, unzip and zipinfo show those characters as question marks. $ zipinfo -1 test.zip my$fil?????? [1] with ? funny\'s * char.txt Note two question marks for each of the original multibyte characters - "°", "à" and "é". $ printf '°àé' | wc -c 6 $ printf '°àé' | wc -m 3 So when you go and try to extract the file, it does not match because, well, the actual file name of the archived file, even that seen by zip, does not have question marks at those positions. But note that when you extract the file, however, the file name is correctly restored. According to unzip TODO file, full support for wide characters is planned for release 6.1. I suggest you use another archiving format like tar, which should not have those limitations (don't know about rar). |