awkcommand-linecommand-line-arguments

How to properly escape single quotes in filenames?


I have files with single quotes in their name, say o'a. I want to process them in awk (gawk-5.3.0): (fd is an alternative to find). Please don't tell me about fd -x option, my command is snippet of a larger one and I am really interested in the awk solution.

fd . | awk '{ print "name: \047" $0 "\047"; cmd="stat -c \"%U\" " $0 ; cmd | getline result ; print result }'

and I get errors:

name: 'o'a'
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file

How to properly escape the quotes in the name in awk ? I tried with gsub but nothing has worked so far.

There are also files with $ sign, so the best solution would be to sanitize names for most of worse situations which of course will occur!


Solution

  • The shell does not interpret contents of single-quoted strings.

    The only unacceptable character in a single-quoted string is single-quote.

    Standalone single-quotes can be safely passed to the shell if escaped by a backslash.

    So:

    fd . | awk -v q=\' '
        function enquote(unsafe,    s){
            s = unsafe
            gsub(q, "&\\\\&&", s)
            return q s q
        }
        {
            print "name: " q $0 q
            cmd = "stat -c %U " enquote($0)
            cmd | getline
            print
            close(cmd)
        }
    '