首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GAWK连接变量

GAWK连接变量
EN

Stack Overflow用户
提问于 2016-11-15 19:33:57
回答 3查看 373关注 0票数 0

我当前的GAWK脚本接受短语文件,并创建regex模式数组,然后将每一行的每一行拆分为\t字符,并循环每一行的前10列,然后检查它是否包含模式数组中的至少一个短语,如果包含,则跳过行,不将其打印到文档中。

问题:

因为短语文件很大,它会产生大量的迭代,使脚本变得非常慢。

(700模式x10列(由选项卡\t分隔)x 1000行。

解决方案:

为了提高速度,我想连接前10列,并检查整个字符串是否至少包含一个模式。我不知道如何在FOR循环中连接行。

工作实例:

代码语言:javascript
复制
gawk 'BEGIN{
FS=" *\t *";
IGNORECASE=1;

while(getline a < "'$phpath'") PATS["^.*"a".*$"]
}

{
    ok=1;
    for(i=1;i<=10;i++){
        for(p in PATS){
            if($i ~ p){
            ok=0
            }
        }
    }

} 
ok {print}' "$f" > "$newPath$filename" 

我的尝试:

代码语言:javascript
复制
gawk 'BEGIN{
    FS=" *\t *";
    IGNORECASE=1;

    while(getline a < "'$phpath'") PATS["^.*"a".*$"]
    }

    {
        phrase="";
        space=" ";
        ok=1;

        for(i=1;i<=10;i++){
            phrase = $space $phrase $i
        }

        for(p in PATS){
            if($phrase ~ p){
                ok=0
            }
        }

    } ok {print}' "$f" > "$newPath$filename"
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-15 19:42:31

在awk中,您像取消引用操作符一样使用$,其中$x的意思是“给我数字在变量x中的列的值”。

要将前10列转换为字符串,请执行以下操作:

代码语言:javascript
复制
    for (i=1; i<=10; i++) {
        # not this => phrase = $space $phrase $i
        phrase = space phrase $i
    }

代码语言:javascript
复制
    for (p in PATS) {
        if (phrase ~ p) {   # <= no $
            ok = 0
            break           # no match, so break the loop early
        }
    }

awk使用像C这样的变量,而不是shell或perl。

您也可以尝试这样做:

代码语言:javascript
复制
gawk -v patternfile="$phpath" '
    BEGIN {
        FS = " *\t *"
        IGNORECASE = 1
        while ((getline a < patternfile) > 0)
            PATS["^.*"a".*$"]
    }
    {
        line = $0
        NF = 10         # this truncates the current record to 10 fields
        ok = 1
        for (p in PATS) 
            if ($0 ~ p) {
                ok = 0
                break
            }
        if (ok) 
            print line
    }
' "$f" > "$newPath$filename"
票数 1
EN

Stack Overflow用户

发布于 2016-11-15 22:08:05

这不是你问题的答案,也许是你问题的答案。

我知道你的问题是关于表现的。

据我所知,您所面临的主要问题之一是您正在使用RegEx。让我解释一下我的观点。在AWK中,当您使用这样的regex : /MyRegExp/时,您使用的是RegEx的编译版本,因此每次您需要检查匹配时只检查它,但是由于您使用的是这样的RegEx:"MyRegExp",所以每次要检查字符串是否匹配时,都会编译它。

你真的在检查RegEx吗?也许你不是,这个函数“索引”对你来说已经足够好了。

为什么不尝试构建一个脚本并运行它呢?相反,根据加载的模式检查第二个文件中的每一行,创建如下脚本:

代码语言:javascript
复制
/pattern1/{
    print
    next
}
/pattern2/{
    print
    next
}
/pattern3/{
    print
    next
}
...
...

然后用第二个文件运行它。不管怎样,我希望这能帮上忙。

票数 0
EN

Stack Overflow用户

发布于 2016-11-15 22:54:41

而(getline a< "'$phpath'")则拍“^.*”a“.*$”

RE ^.*"a".*$等价于a。您可以直接使用|来声明OR条件,而不是迭代这些模式。

如果您的输入文件是

代码语言:javascript
复制
every
good
boy
does
fine

您的RE变成了every|good|boy|does|fine,您的代码被简化为

代码语言:javascript
复制
$0 ~ pattern { 
    for (i=1; i<=10; i++) {
        if( $i ~ pattern ) { 
           print "$f" > "$newPath$filename" # what's $f?  
           break
        }
    }
}

也就是说,先扫描整条线。如果它找到了什么,就迭代前10列。我敢打赌这比无条件的迭代要快。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40618230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档