代码之家  ›  专栏  ›  技术社区  ›  loretoparisi

每行和保留列的awk exec命令

  •  1
  • loretoparisi  · 技术社区  · 6 年前

    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)
    

    所以需要一个 line trn.convert 并将结果写入 标准 没有任何平行性。

    由于这个原因(在多行输入方面缺乏并行性),性能受到数据集大小(行数)的限制。

    here . 示例如下

    KN   ಐಕ್ಯತೆ ಕ್ಷೇಮಾಭಿವೃದ್ಧಿ ಸಂಸ್ಥೆ  ವಿಜಯಪುರ
    KN   ಹೊರಗಿನ ಸಂಪರ್ಕಗಳು 
    KN    ಮಕ್ಕಳ ಸಾಹಿತ್ಯ ಮತ್ತು ಸಾಂಸ್ಖ್ರುತಿಕ ಕ್ಷೇತ್ರದಲ್ಲಿ ಸೇವೆ ಸಲ್ಲಿಸುತ್ತಿರುವ ಸಂಸ್ಠೆ ಮಕ್ಕಳ ಲೋಕ  
    

    而基于最后接受答案的示例脚本是 here

    2 回复  |  直到 6 年前
        1
  •  3
  •   Charles Duffy    6 年前

    不使用调用shell awk . shell本身避免将数据当作代码来处理,除非明确指示这样做——但是当您使用 system() popen() ,就像awk代码在这里所做的那样, 一切 作为参数传递是在上下文中解析的,在上下文中,数据能够转义其引号并被视为代码。


    简单方法:一 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
    

    快速接近:一 起诉 全部的

    如果 起诉 每行输入生成一行输出,您可以做得更好,将一个流与所有第一列和第二个字符串与其余行的翻译粘贴在一起,这样就只需要一个 起诉

    #!/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
    
        2
  •  1
  •   oguz ismail FCulig    6 年前

    您可以通过管道将第2列传输到您的命令,并使用命令的输出对其进行更改,如下面在awk中所示。

    {
        cmd = "echo "$2" | indictrans -s asm -t eng --ml --build-lookup"
        cmd | getline $2
        close(cmd)
    } 1
    

    如果 SOURCE TARGET

    {
        cmd = "echo "$0" | indictrans -s "SOURCE" -t "TARGET" --ml --build-lookup"
        cmd
        close(cmd)
    }