Reputation: 145
So I've been doing some reading on AWK but I seem to be having a problem executing the following code:
curl http://website.com/users.csv | tac | tac | sed '101,400!d' | grep "female" |
awk -F',' '{ print "sudo useradd -Db /home/gender/female" " " $1 " " "-c" " " \"$5 " " $6\""}' |
bash
I'm trying to escape the double quotes immediately before $5
and after $6
so that I can either do a system call from AWK or just pipe to bash. For some reason my escape characters are not working. I read this GNU AWK summary on escape sequences to no avail.
How can I accomplish this?
The output should look like this:
sudo useradd -Db /home/gender/female dinessid1965 -c "Marina Propst"
And the input looks like this:
reatim,Shephoi8v,female,Ms.,Eija,Kankkunen,4721 Pearcy Avenue,Fort Wayne,IN,46804,,260-715-7242,2/22/84,Pisces,Dermatologist
Upvotes: 2
Views: 1998
Reputation: 52152
Firstly, for the escaping: you make your life harder than necessary by quoting everything separately. Instead of
print "sudo useradd -Db /home/gender/female" " " $1 " " "-c" " " \"$5 " " $6\""
you could write
print "sudo useradd -Db /home/gender/female " $1 " -c " \"$5 " " $6\""
at which point it becomes a little more obvious that there is something off with the quoting: GNU Awk complains that the \
is not the last character of the line.
You could write it like this, with the escaped quote \"
between quotes:
print "sudo useradd -Db /home/gender/female " $1 " -c \"" $5 " " $6 "\""
or, easier to read, specify a variable that contains the double quote (see the manual):
awk -v dq='"' '{ print "sudo useradd -Db /home/gender/female " $1 " -c " dq $5 " " $6 dq }'
Secondly, your whole chain can be simplified: tac | tac
does nothing, and what grep and sed do can be done by awk:
curl http://website.com/users.csv |
awk -F, -v dq='"' '/female/ && NR >= 101 && NR <= 400 { \
print "sudo useradd -Db /home/gender/female " dq $1 dq " -c " dq $5 " " $6 dq }' |
bash
Alternatively, to avoid some of the ugliness of adding spaces between variables using print
, we could use printf
(thanks to Ed Morton for the nudge):
curl http://website.com/users.csv |
awk -F, '/female/ && NR >= 101 && NR <= 400 { \
printf "sudo useradd -Db /home/gender/female \"%s\" -c \"%s %s\"\n", $1, $5, $6 }' |
bash
Notice how also the expansion of $1
is quoted in the last two commands to prevent side effects of characters special to the shell (or even malicious commands).
Upvotes: 2
Reputation: 385650
You're making this harder than necessary by involving awk at all. It's also dangerous because you're not quoting the contents of $1
, $5
, and $6
for the shell. If they contain any funny characters, you're in trouble.
You can do it entirely in bash, safely:
curl http://website.com/users.csv | sed '101,400!d' | grep "female" |
while IFS=, read -a words; do
sudo useradd -Db /home/gender/female "${words[0]}" -c "${words[4]} ${words[5]}"
done
Although for more safety you might need to ensure that the username field doesn't contain anything fishy (e.g. start with ../
). I don't know how much checking useradd
does.
Upvotes: 1
Reputation: 67507
you're using too many quotes!
Here is a simple example you can change into your format
$ echo dinessid1965,two,three,four,Marina,Propst |
awk -F, -v q='"' '{print "sudo ...", $1, "-c", q $5, $6 q}'
sudo ... dinessid1965 -c "Marina Propst"
Upvotes: 0