从 awk 调用 python 脚本
Posted
技术标签:
【中文标题】从 awk 调用 python 脚本【英文标题】:Calling a python script from awk 【发布时间】:2021-10-19 02:03:19 【问题描述】:我有一个没有大约 150k 行和两列的文件。我需要在第一个字段上运行一个 python 脚本,并将其输出保存为第三列,这样更改看起来像这样:
原始文件:
Col1 Col2
d 2
e 4
f 6
New file:
Col1 Col2 Col3
d 2 output
e 4 output
f 6 output
我无法从 awk 内部运行脚本。
cat original.list | awk -F" " ' `/homes/script.py $1`'
如果可以的话,我希望将其保存为变量,并将新变量以及 $1 和 $2 打印到新文件中。
提前致谢(相关问题here)
【问题讨论】:
看这个:Assigning system command's output to variable 为什么不用python完成所有的任务呢? awk 不是唯一可以拆分列的语言。 【参考方案1】:您链接的“相关问题”的答案(以及在 cmets 中发布的问题)实际上解决了您的问题, 它只需要适应您的具体情况。
cat original.list | awk -F" " ' `/homes/script.py $1`'
cat
在这里没用,因为awk
可以自己打开和读取文件
您不需要-F" "
,因为awk
默认会按空格分割字段
反引号``不会运行你的脚本,that's a shell (discouraged)
feature,在
awk
我们可以使用command | getline var
来执行一个命令并存储它
(第一行)在变量中输出。来自man awk
:
命令 |获取线变量
将一条记录从命令传送到 var。
使用您的示例文件:
$ cat original
Col1 Col2
d 2
e 4
f 6
$
还有一个假人script.py
:
$ cat script.py
#!/bin/python
print("output")
$
我们可以这样做:
$ awk '
NR == 1 print $0, "Col3"
NR > 1 cmd="./script.py " $1; cmd | getline out; close(cmd); print $0, out
' original
Col1 Col2 Col3
d 2 output
e 4 output
f 6 output
$
第一个动作在输入的第一行运行,将Col3
添加到标题中并
避免将Col1
传递给python 脚本。
在另一个动作中,我们首先构建将$1
连接到
脚本的路径,然后我们运行它并将它的第一行输出存储在out
变量(我假设您的 python 脚本输出只有一行)。 close(cmd)
很重要,因为在 getline
之后,管道读数
来自cmd
的输出将保持打开状态,对许多记录执行此操作可能会导致
像too many open files
这样的错误。最后我们打印$0
和cmd
's
输出。
第三列的格式看起来有点不对劲,你可以从
awk
使用printf
或与column
等外部程序一起使用,例如:
$ awk '
NR == 1 print $0, "Col3"
NR > 1 cmd="./script.py " $1; cmd | getline out; close(cmd); print $0, out
' original | column -t
Col1 Col2 Col3
d 2 output
e 4 output
f 6 output
$
最后,在 150k 行文件上执行所有这些操作意味着调用 python 脚本 150k 次等..,这可能是一项缓慢的任务,我认为性能可能是 通过直接在 python 脚本中执行所有操作来改进 在 cmets 中建议,但无论它是否适用于您的具体情况, 超出此问题/答案的范围。
【讨论】:
以上是关于从 awk 调用 python 脚本的主要内容,如果未能解决你的问题,请参考以下文章