我有一个大型数据集文件,其中有两列
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"
,它不起作用。如何正确执行此命令并转义参数?
[UPDATE] 这是部分解决方案,我受到建议的
的启发#!/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)
因此它需要从line
中取出一个stdin
,使用某个库trn.convert
处理数据,然后将结果写入stdout
,而没有任何并行性。
由于这个原因(就多行输入而言缺乏并行性),性能受到数据集大小(行数)的限制。
here提供了示例输入两列数据集(1000行)。一个示例示例是
KN ಐಕ್ಯತೆ ಕ್ಷೇಮಾಭಿವೃದ್ಧಿ ಸಂಸ್ಥೆ ವಿಜಯಪುರ
KN ಹೊರಗಿನ ಸಂಪರ್ಕಗಳು
KN ಮಕ್ಕಳ ಸಾಹಿತ್ಯ ಮತ್ತು ಸಾಂಸ್ಖ್ರುತಿಕ ಕ್ಷೇತ್ರದಲ್ಲಿ ಸೇವೆ ಸಲ್ಲಿಸುತ್ತಿರುವ ಸಂಸ್ಠೆ ಮಕ್ಕಳ ಲೋಕ
,基于最后接受的答案的示例脚本为here
答案 0 :(得分:3)
请勿使用awk
调用shell。除非明确指示否则,shell本身避免将数据视为代码,除非您使用system()
或popen()
,就像awk代码在这里所做的那样,作为参数传递的一切在数据能够转义引用并被视为代码的上下文中进行解析。
indictrans
如果要为要执行的每一行单独复制indictrans
,请使用:
while read -r col1 rest; do
printf '%s\t%s\n' "$col1" "$(indictrans -s asm -t eng --ml --build-lookup <<<"$rest")"
done <in.txt >out.txt
indictrans
处理所有行如果indictrans
每输入一行生成一行输出,则可以做得更好,方法是将一个流与所有第一列粘贴在一起,然后将第二个字符串与其余各行的翻译粘贴在一起,这样只需运行indictrans
的一个副本:
#!/usr/bin/env bash
# ^^^^- not compatible with /bin/sh
paste <(<in.txt awk '{print $1}') \
<(<in.txt sed -E 's/^[^[:space:]]*[[:space:]]//' \
| indictrans -s asm -t eng --ml --build-lookup) \
>out.txt
答案 1 :(得分:1)
您可以将第2列传送到您的命令,并使用如下所示的awk命令输出来更改它。
{
cmd = "echo "$2" | indictrans -s asm -t eng --ml --build-lookup"
cmd | getline $2
close(cmd)
} 1
如果SOURCE
和TARGET
是awk变量
{
cmd = "echo "$0" | indictrans -s "SOURCE" -t "TARGET" --ml --build-lookup"
cmd
close(cmd)
}