From: Guillaume Dargaud on
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
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
> 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
> 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
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).