所以我一直在读AWK,但我似乎在执行以下代码时出现问题:
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
我试图在$5
之前和$6
之后立即转义双引号,这样我就可以从AWK进行系统调用,或者只是管道进行bash。由于某种原因,我的转义字符不起作用。我读了关于转义序列的这个GNU AWK摘要无济于事。
我怎样才能做到这一点?
输出应如下所示:
sudo useradd -Db /home/gender/female dinessid1965 -c "Marina Propst"
输入如下:
reatim,Shephoi8v,female,Ms.,Eija,Kankkunen,4721 Pearcy Avenue,Fort Wayne,IN,46804,,260-715-7242,2/22/84,Pisces,Dermatologist
答案 0 :(得分:2)
首先,对于逃避:你通过单独引用所有内容来使你的生活更加艰难。而不是
print "sudo useradd -Db /home/gender/female" " " $1 " " "-c" " " \"$5 " " $6\""
你可以写
print "sudo useradd -Db /home/gender/female " $1 " -c " \"$5 " " $6\""
此时引用的内容变得更加明显:GNU Awk抱怨\
不是该行的最后一个字符。
您可以这样写,引号之间的转义引用\"
:
print "sudo useradd -Db /home/gender/female " $1 " -c \"" $5 " " $6 "\""
或更容易阅读,指定包含双引号的变量(请参阅manual):
awk -v dq='"' '{ print "sudo useradd -Db /home/gender/female " $1 " -c " dq $5 " " $6 dq }'
其次,你的整个链可以简化:tac | tac
什么都不做,grep和sed可以用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
或者,为了避免使用print
在变量之间添加空格的一些丑陋,我们可以使用printf
(感谢Ed Morton轻推):
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
注意最后两个命令中引用$1
的扩展是如何防止shell特有的字符(甚至是恶意命令)的副作用。
答案 1 :(得分:1)
你完全涉及到awk,这使得这比必要的更难。它也很危险,因为您没有为shell引用$1
,$5
和$6
的内容。如果它们包含任何有趣的角色,那你就麻烦了。
你可以完全用bash安全地完成它:
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
虽然为了更加安全,您可能需要确保用户名字段不包含任何可疑内容(例如,以../
开头)。我不知道检查useradd
有多少。
答案 2 :(得分:0)
以下是一个可以更改为格式的简单示例
$ echo dinessid1965,two,three,four,Marina,Propst |
awk -F, -v q='"' '{print "sudo ...", $1, "-c", q $5, $6 q}'
sudo ... dinessid1965 -c "Marina Propst"