【发布时间】:2019-02-25 01:02:51
【问题描述】:
我有一个包含两列的大型数据集文件
AS জীৱবিজ্ঞানবিভাগ
AS চেতনাদাস
AS বৈকল্পিক
我想在第二列上运行我的命令,存储结果并获得具有相同列格式的输出:
AS jibvigyanvibhag
AS chetanadas
AS baikalpik
我的命令是这个管道:
echo "$0" | indictrans -s asm -t eng --ml --build-lookup
所以我这样做
awk -v OFS="\t" '{ print "echo "$2" | indictrans -s asm -t eng --ml --build-lookup" | "/bin/sh"}' in.txt > out.txt
但这不会保留列,它只是像这样打印出第一列
jibvigyanvibhag
chetanadas
baikalpik
我的解决方案如下
awk -v OFS="\t" '{ "echo "$2" | indictrans -s asm -t eng --ml --build-lookup" | getline RES; print $1,$2,RES}' in.txt > out.txt
会打印出来
AS জীৱবিজ্ঞানবিভাগ jibvigyanvibhag
AS চেতনাদাস chetanadas
AS বৈকল্পিক baikalpik
现在我想对命令进行参数化,但是这里的转义看起来很奇怪:
"echo "$0" | indictrans -s $SOURCE -t $TARGET --ml --build-lookup"
它不起作用。如何正确执行该命令并转义参数?
[更新] 这是我受到建议的启发而得出的部分解决方案
#!/bin/bash
SOURCE=asm
TARGET=eng
IN=$2
OUT=$3
awk -v OFS="\t" '{
CMD = "echo "$2" | indictrans -s asm -t eng --ml --build-lookup"
CMD | getline RES
print $1,RES
close(CMD)
}' $IN > $OUT
我仍然无法摆脱变量,似乎我无法像往常一样用-v定义
awk -v OFS="\t" -v source=$SOURCE -v target=$TARGET '{
CMD = "echo "$2" | indictrans -s source -t target --ml --build-lookup"
...
注意事项。
indictrans 进程处理stdin 并以这种方式写入stdout:
for line in ifp:
tline = trn.convert(line)
ofp.write(tline)
# close files
ifp.close()
ofp.close()
在哪里
ifp = codecs.getreader('utf8')(sys.stdin)
ofp = codecs.getwriter('utf8')(sys.stdout)
所以它从stdin 中提取一个line,使用某个库trn.convert 处理数据,并将结果写入stdout,没有任何并行性。
出于这个原因(在多行输入方面缺乏并行性),性能受到数据集大小(行数)的限制。
here 提供了一个示例输入两列数据集(1K 行)。示例示例是
KN ಐಕ್ಯತೆ ಕ್ಷೇಮಾಭಿವೃದ್ಧಿ ಸಂಸ್ಥೆ ವಿಜಯಪುರ
KN ಹೊರಗಿನ ಸಂಪರ್ಕಗಳು
KN ಮಕ್ಕಳ ಸಾಹಿತ್ಯ ಮತ್ತು ಸಾಂಸ್ಖ್ರುತಿಕ ಕ್ಷೇತ್ರದಲ್ಲಿ ಸೇವೆ ಸಲ್ಲಿಸುತ್ತಿರುವ ಸಂಸ್ಠೆ ಮಕ್ಕಳ ಲೋಕ
而基于最后接受答案的示例脚本是here
【问题讨论】:
-
您是否有理由为此使用
awk?该代码存在严重的安全漏洞;编写一个根本不尝试在管道中涉及awk的安全实现会更容易。 -
...shell 本身对来自参数扩展结果的数据的处理方式与对代码的处理方式不同,但如果将某些内容以与代码相同的字符串传递到 shell , 这样的安全预防措施是有争议的。
-
顺便说一句,您可以将多行输入流式传输到
indictrans吗?保持单个长时间运行的实例打开可能会更有效;只要它每行输入生成一行输出,就可以轻松生成整个流,然后将其与带外的第一列连接起来。这样你也会获得更好的性能。 -
当然——改进的空间是速度而不是简单;如果您要翻译数百行代码,更简单的方法会运行数百个
indictrans副本,而代码稍多的则只运行一个(并通过它移动所有一百行),因此启动 Python 所涉及的开销要少得多口译员一遍又一遍。仅从您显示的代码来看,我认为更高性能的版本可能会正常工作,但如果不能正常工作,那么 minimal reproducible example (理想情况下,如果它是公开的,则带有指向indictrans的链接)将是需要。