Home > Mobile >  How to add quotes for awk when single and double quotes are already used?
How to add quotes for awk when single and double quotes are already used?

Time:11-27

I want to write an alias so that my squeue command outputs only the simulations that are running. For my squeue command, I've an alias in my .bashrc as follow

alias sq='squeue -u as1056 --format="%.18i %.36j %.8u %.2t %.10M %.10L %.6D %.6C %.12P %R"'

With this, I can output the running simulations as

sq | awk '$4 == "R" {print $0}'

This works as intended in the command line. I now want to add this command as an alias

alias sqrun='sq | awk "$4 == \"R\" {print $0}"'

As you can see, the single quotes are already exhausted after the equal to sign and hence, double quotes are needed after the awk command. However, to match the pattern in column 4, I need to specify another string. Since single quote and double quotes have already been used, I'm not sure how I can specify a string in this scenario. I tried escaping the double quotes using backslash but it throws error:

awk: cmd. line:1:  == "R" {print -bash}
awk: cmd. line:1:  ^ syntax error

So how should I specify an alias in such scenario?

Edit1: There's a dirty way of doing it by matching a simple R pattern across the sq command. The problem is that it often matches columns which contain the word "DRAINED". So I can use sed to delete such lines. So something like

sq | awk "/R/ {print $0}" | sed "/DRAINED/d"

won't run into the problem of having 3 quotes in the command. But I want to avoid this approach as it's not generic and may give erroneous results if there ever happens to be a column containing R and not containing the word "DRAINED".

PS: This is my first ever question on stackoverflow, so I'll appreciate your feedback if you notice any mistakes in the way I've asked this question!

CodePudding user response:

I would go with a simple:

alias sqrun='sq | awk '\''$4 == "R" {print $0}'\'

or with a function, like @DiegoTorresMilano suggested (but unlike aliases, it's not so easy to find a function name that you forgot):

sqrun() { sq | awk '$4 == "R" {print $0}'; }

or if there are several aliases to define:

#!/bin/sh

# A little magic that will show you the way:
while IFS='' read -r cmd
do
    # define a dummy alias
    alias "unamed=$cmd"
    # then show it
    alias unamed
done <<'EOF'
squeue -u as1056 --format="%.18i %.36j %.8u %.2t %.10M %.10L %.6D %.6C %.12P %R"
sq | awk '$4 == "R" {print $0}'
EOF

now you can copy paste the output into your .bashrc and set a name for your aliased commands

notes:

  • <<'EOF' ... EOF is a quoted here-document; It will feed the stdin of a command (the while loop) with its content. When quoted it means that the shell won't expand anything inside of it.

  • The read command reads a line from stdin (feeded with the here-document). The IFS='' and the -r option are there to prevent read from modifying the line.

CodePudding user response:

you can chain single quoted sections by double quoting single quotes

alias sqrun='sq | awk '"'"' $4 == "R" {print $0} '"'"' '

added extra spaces for clarity but not needed. However these nested quotes can become really hard to read and probable not a good idea except only for trivial cases and throw away scripts.

CodePudding user response:

The awk script contains $ and when you change the quotes around the awk script from ' to ", it makes bash treat them as variables to substitute. You have to also escape $:

alias sqrun='sq | awk "\$4 == \"R\" {print \$0}"'
  • Related