剪贴板中包含以下内容:
curl "foo" --compressed ;
curl "bar" --compressed ;
curl "baz" --compressed ;
以下命令为每个剪贴板行创建一行:
pbpaste | awk '{"pwgen 10 1" | getline pass; print substr($0, 1, length($0) -1) ">>myfile-" pass ".jpg"}'
生成以下输出:
curl "foo" --compressed >>myfile-du7EeHegh7.jpg
curl "bar" --compressed >>myfile-du7EeHegh7.jpg
curl "baz" --compressed >>myfile-du7EeHegh7.jpg
问题:
这里的问题是,pwgen 10 1
似乎在开始时只执行一次,而我希望它为每个新的剪贴板行执行,因此为每行生成一个新的唯一文件名。如何确保pwgen
重复调用而不是在开始时只执行一次?
期望的输出:
# each filename is unique
curl "foo" --compressed >>myfile-zus83j10ai.jpg
curl "bar" --compressed >>myfile-nbjfo2pa9d.jpg
curl "baz" --compressed >>myfile-ahqdugpo90.jpg
答案1
在 awk 中使用外部命令并使用getline from a Pipe
,最好将命令分配给一个变量my_command="my external command here"
,然后用它调用my_command |getline to_save
它,你应该close(my_command)
它是为了使每次运行的输出都不同;还建议执行close(my_command)
inBEGIN{...}
块以确保没有命令为my_command
.
另外对 getline 返回代码进行测试,如果成功则继续;所以你必须这样做:
pbpaste |awk 'BEGIN{ close(cmd); }
{ cmd="pwgen 10 1";
if (cmd | getline pass) {
print substr($0, 1, length($0) -1) ">>myfile-" pass ".jpg";
close(cmd);
} else { print "running command failed!"; exit 1; }
}'
然而,如果命令本身失败, getline 仍然会返回成功返回代码,因为我们不检查命令成功/失败,为了对命令状态进行测试,我们可以这样做:
pbpaste |awk 'BEGIN{ close(cmd); }
{ cmd="pwgen 10 1 || echo failed";
if ((cmd | getline pass)>0 && pass!="failed") {
print substr($0, 1, length($0) -1) ">>myfile-" pass ".jpg";
close(cmd);
} else { print "running command failed!"; exit 1; }
}'
引用手册:
如果文件名相同或相同的 shell 命令
getline
在 awk 程序执行期间多次使用(请参阅使用 getline 显式输入部分),文件被打开(或命令被执行)仅限第一次。此时,将从该文件或命令中读取第一条输入记录。下次将同一个文件或命令与 getline 一起使用时,将从中读取另一条记录,依此类推。
从上面的链接使用 getline 显式输入提及:
getline 命令如果找到记录则返回 1,如果遇到文件末尾则返回 0。如果获取记录时出现错误,例如无法打开文件,则 getline 返回 -1。在这种情况下,gawk 将变量 ERRNO 设置为描述发生的错误的字符串。
也可以看看: