我有一个 C 语言程序,我想在 shell 脚本中使用 awk 来调用它。我怎么能做这样的事情?
8 回答
一种更健壮的方法是使用getline()GNU 的函数awk来使用管道中的变量。在表单cmd | getline结果中,cmd运行,然后将其输出通过管道传输到getline. 1如果有输出,0如果 EOF,-1失败时返回。
BEGIN如果命令不依赖于文件的内容,例如简单date或ls.
上面的一个简单例子是
awk 'BEGIN {
cmd = "ls -lrth"
while ( ( cmd | getline result ) > 0 ) {
print result
}
close(cmd);
}'
当要运行的命令是文件的列内容的一部分时,您会cmd在 main 中生成字符串,{..}如下所示。例如,考虑一个$2包含文件名的文件,并且您希望将其替换为md5sum文件的哈希内容。你可以做
awk '{ cmd = "md5sum "$2
while ( ( cmd | getline md5result ) > 0 ) {
$2 = md5result
}
close(cmd);
}1'
涉及外部命令的另一个常见用法awk是在date处理期间,当您awk不支持开箱即用的时间函数时mktime(),strftime()函数。
考虑一种情况,当您将 Unix EPOCH 时间戳存储在列中并且您希望将其转换为人类可读的日期格式。假设 GNUdate可用
awk '{ cmd = "date -d @" $1 " +\"%d-%m-%Y %H:%M:%S\""
while ( ( cmd | getline fmtDate) > 0 ) {
$1 = fmtDate
}
close(cmd);
}1'
对于输入字符串
1572608319 foo bar zoo
上面的命令产生的输出为
01-11-2019 07:38:39 foo bar zoo
可以定制该命令以修改date给定行中任何列上的字段。请注意,这-d是一个 GNU 特定的扩展,*BSD 变体支持-f(虽然不完全相似-d)。
有关更多信息,请参阅 awk.freeshell.org页面上getline的这篇AllAboutGetline文章。
有几种方法。
awk 有一个
system()可以运行 shell 命令的函数:system("cmd")您可以打印到管道:
print "blah" | "cmd"您可以使用 awk 构造命令,并将所有输出通过管道传输到 shell:
awk 'some script' | sh
像这样简单的东西会起作用
awk 'BEGIN{system("echo hello")}'
和
awk 'BEGIN { system("date"); close("date")}'
这真的取决于 :) 方便的 linux 核心 utils ( info coreutils) 之一是xargs. 如果您正在使用awk,您可能会想到一个更复杂的用例 - 您的问题不是很详细。
printf "1 2\n3 4" | awk '{ print $2 }' | xargs touch
将执行touch 2 4。这里touch可以替换为您的程序。更多信息info xargs和man xargs(真的,阅读这些)。我相信你想touch用你的程序替换。
前面提到的脚本的细分:
printf "1 2\n3 4"
# Output:
1 2
3 4
# The pipe (|) makes the output of the left command the input of
# the right command (simplified)
printf "1 2\n3 4" | awk '{ print $2 }'
# Output (of the awk command):
2
4
# xargs will execute a command with arguments. The arguments
# are made up taking the input to xargs (in this case the output
# of the awk command, which is "2 4".
printf "1 2\n3 4" | awk '{ print $2 }' | xargs touch
# No output, but executes: `touch 2 4` which will create (or update
# timestamp if the files already exist) files with the name "2" and "4"
更新在原始答案中,我使用echo而不是printf. 但是,printf正如评论所指出的那样,这是更好、更便携的替代方案(可以找到与讨论的重要链接)。
我使用 awk 的强大功能删除了一些已停止的 docker 容器。在将cmd字符串传递给system.
docker ps -a | awk '$3 ~ "/bin/clish" { cmd="docker rm "$1;system(cmd)}'
在这里,我使用模式为“/bin/clish”的第三列,然后在第一列中提取容器 ID 来构造我的cmd字符串并将其传递给system.
#!/usr/bin/awk -f
BEGIN {
command = "ls -lh"
command |getline
}
在 awk 脚本中运行“ls -lh”
我能够通过以下方法完成此操作
cat ../logs/em2.log.1 |grep -i 192.168.21.15 |awk '{system(`date`); print $1}'
awk 有一个名为 system 的函数,它使您能够在 awk 的输出中执行任何 linux bash 命令。