Search code examples
linuxzshaliasoh-my-zsh

How do I escape special characters in oh-my-zsh alias?


So I am trying to create an alias that would list files in current directory like "ls -lAh" would, but only with specific columns that I want. So I've come up with this command:

ls -lAh | awk 'BEGIN{FS=" "; OFS=" "} {print $6,$7,$8,$5,$9}'

This would only print columns that I need, which are date and time, file size and file name in that order.

However if I want to create an alias for this command, I obviously need to escape a lot of characters so they get interpreted properly, but I am failing to do so. Sometimes when I put a backslash in front of a single quote or a dollar sign, it just breaks one way or the other and I can't make it work.

Please help me understand how I'm supposed to escape the special characters so this gets interpreted correctly.

In case it changes anything, I'm on MacOS. Please do ask for clarifications if needed.

Edit:- Here is what I tried when attempting to actually create an alias:

alias lah='ls -lAh | awk \'BEGIN\{FS=" "; OFS=" "\} \{print \$6,\$7,\$8,\$5,\$9}\''

I tried putting backslashes before every special character, on my first try I just put them before the single quotes, that didn't work and it was telling me something like zsh: parse error at {. Then I put a backslash before each curly brace, and that didn't work, apparently dollar signs are also special characters, so I put backslashes before those, but then whenever I press return after typing the command, it makes a new line that says quote>, where I had to put a single quote to end the command, and when I do that it prints this: zsh: command not found: \{print.


Solution

  • The problem is how to correctly quote with single quotes a string that already contains single quotes.

    ls -lAh | awk 'BEGIN{FS=" "; OFS=" "} {print $6,$7,$8,$5,$9}'
    

    To get a correctly quoted string easily you could use ZSH's key sequence ESC ' (single quote).

    • Type the string you want to quote, e.g.
      ls -lAh | awk 'BEGIN{FS=" "; OFS=" "} {print $6,$7,$8,$5,$9}'
    • Press ESC followed by ' (single quote). In your example this should give you something like
      'ls -lAh | awk '\''BEGIN{FS=" "; OFS=" "} {print $6,$7,$8,$5,$9}'\'
    • Continue with the rest of your command or copy&paste the quoted string into your editor.

    In general, to quote a single quote inside single quotes you need to insert a closing quote ', an escaped quote \' and if necessary an opening quote ' like this:

    alias lah='ls -lAh | awk '\''BEGIN{FS=" "; OFS=" "} {print $6,$7,$8,$5,$9}'\'