filenames with blanks, newlines, punctuations, and escape characters.

filenames with blanks, newlines, punctuations, and escape characters.

Post by Robert Kat » Thu, 13 Jan 2005 13:42:58



Does anyone have pointers to threads discussing the inherent pitfalls of
scripts designed to generalize file renaming, find files, xargs ,...,
etc for those nonstandard filenames?  I know there have been some great
discussions, but I can't seem to find the stuff.

--
Regards,

---Robert

 
 
 

filenames with blanks, newlines, punctuations, and escape characters.

Post by Bill Seiver » Thu, 13 Jan 2005 14:55:56



> Does anyone have pointers to threads discussing the inherent pitfalls
> of scripts designed to generalize file renaming, find files, xargs
> ,..., etc for those nonstandard filenames?  I know there have been
> some great discussions, but I can't seem to find the stuff.

Except for newlines, I would use find ... -print > file, then use awk on
file to escape any
embedded double quotes and backslashes, and add double quotes around
each filename.

find . -print > /tmp/filelist 2>/dev/null
awk '{gsub (/\"/, "\\\""); gsub (/\\/, "\\\\"); \
    printf ("\"%s\"\n", $0);}' /tmp/filelist > /tmp/newfile

Thanks.
Bill Seivert


 
 
 

filenames with blanks, newlines, punctuations, and escape characters.

Post by Stephane CHAZELA » Thu, 13 Jan 2005 17:36:41


2005-01-11, 22:55(-07), Bill Seivert:
[...]
Quote:> Except for newlines, I would use find ... -print > file, then use awk on
> file to escape any
> embedded double quotes and backslashes, and add double quotes around
> each filename.

> find . -print > /tmp/filelist 2>/dev/null
> awk '{gsub (/\"/, "\\\""); gsub (/\\/, "\\\\"); \
>     printf ("\"%s\"\n", $0);}' /tmp/filelist > /tmp/newfile

[...]

You'd better use single quotes instead of double quotes. Inside
double quotes $, \ and ` " are still special (for shells at
least).

And for xargs, note that the only portable escape way is with
backslashes. Unfortunately, the single and double quote handling
is not the same depending on the xargs implementation.

So,

find .//. -print |sed 's/./\\&/g' | awk '
     {
       if (NR > 1) {
         printf "%s", line
         if ($0 !~ /\\\/\\\//) printf "\\"
         print ""
       }
       line = $0
     }
     END { print line }' | xargs

Which also handles newline characters (solution by Gunnar
Ritter).

--
Stephane