Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix性能改进-可能正在使用AWK_Unix_Awk - Fatal编程技术网

Unix性能改进-可能正在使用AWK

Unix性能改进-可能正在使用AWK,unix,awk,Unix,Awk,我有两个文件File1.txt(它有6列由管道分隔)和File2.txt(它有2列由管道分隔) File1.txt NEW|abcd|1234|10000000|Hello|New_value| NEW|abcd|1234|20000000|Hello|New_value| NEW|xyzq|5678|30000000|myname|New_Value| 10000000|10000001>10000002>10000003>10000004 19000000|1000000

我有两个文件File1.txt(它有6列由管道分隔)和File2.txt(它有2列由管道分隔)

File1.txt

NEW|abcd|1234|10000000|Hello|New_value|
NEW|abcd|1234|20000000|Hello|New_value|
NEW|xyzq|5678|30000000|myname|New_Value|
10000000|10000001>10000002>10000003>10000004
19000000|10000000>10000001>10000002>10000003>10000004
17000000|10000099>10000000>10000001>10000002>10000003>10000004
20000000|10000001>10000002>10000003>10000004>30000000
29000000|20000000>10000001>10000002>10000003>10000004
File2.txt

NEW|abcd|1234|10000000|Hello|New_value|
NEW|abcd|1234|20000000|Hello|New_value|
NEW|xyzq|5678|30000000|myname|New_Value|
10000000|10000001>10000002>10000003>10000004
19000000|10000000>10000001>10000002>10000003>10000004
17000000|10000099>10000000>10000001>10000002>10000003>10000004
20000000|10000001>10000002>10000003>10000004>30000000
29000000|20000000>10000001>10000002>10000003>10000004
目标是针对File1.txt中的每一行,我必须选择第4列,并在File2.txt中搜索该值。如果在File2.txt中找到任何匹配项,那么我必须从File2.txt中提取所有行,但只提取第一列

这可能会在目标文件中产生更多的记录。输出应如下所示(最后一列123来自固定变量)

我可以写一个如下的解决方案,它也给了我正确的输出。但是当File1.txt和File2.txt都有大约150K行时,这个需要21分钟。生成的最终目标文件中有超过1000万行

VAL1=123

for ROW in `cat File1.txt`
do
  Fld1=`echo $ROW | cut -d'|' -f'1-3'`
  Fld2=`echo $ROW | cut -d'|' -f4`
  Fld3=`echo $ROW | cut -d'|' -f'5-6'`

  grep -i $Fld2 File2.txt | cut -d'|' -f1  > File3.txt
  sed 's/^/'$Fld1'|/g' File3.txt | sed 's/$/|'${Fld3}'|'${VAL1}'/g' >> Target.txt

done 

但我的问题是这个解决方案可以优化吗?是否可以使用AWK或任何其他方法更快地重新编写此文件?

我猜您的性能下降是由于重复将
grep
sed
sed
的文件读入内存而造成的。如果您可以将File2的内容存储在内存中(甚至可以存储在临时SQLite DB中),那么应该可以加快速度。然后,您将逐行处理File1,并对File2键进行简单的查找


在运行脚本以跟踪RAM和CPU使用情况时,运行
htop
或某些活动监视器会很有帮助。

我很确定这会更快(因为在单个awk或sed进程中使用隐式循环通常比在shell循环中反复调用隐式循环要快),但您必须尝试一下,并让我们知道:

编辑:此版本应解决输出中的重复问题

$ cat a.awk
NR == FNR {
    for (i=1; i<=NF; ++i) {
        if ($i in a)
            a[$i] = a[$i] "," $1
        else
            a[$i] = $1;
    }
    next 
}

$4 in a {
    split(a[$4], b, ",")
    for (i in b) {
        if (!(b[i] in seen)) {
            print $1, $2, $3, b[i], $5, $6, new_value
            seen[b[i]]
        }
    }
    delete seen
}

稍微优化的gnu awk脚本:

awk 'NR==FNR{a[$4]=$0;next}
     {
        for(i=1; i<=NF; i++){
          if($i in a) 
            print gensub("[^|]+\\|",$1 "|",4,a[$i])
        }
     }' FS='|' file1 FS='[|>]' file2
awk'NR==FNR{a[$4]=$0;next}
{
对于(i=1;i]'文件2
第一条语句用file1的内容填充数组
a

第二个block语句遍历file2的所有字段,并打印与file2的第一个字段匹配的数组内容


打印的字符串使用awk
gensub
函数进行修改。它只允许更改找到的第四个图案。

性能当然提高了。但最终结果不匹配。我的意思是使用我的旧块说我得到了x行数,现在我得到了y行数,其中y>x。我试图找出哪些行是多余的。看起来您的解决方案是在文件中写入重复项。我使用了
awk-v new_value=123-v OFS=“|”-f a.awk FS='[|>]'File2.txt FS='|'File1.txt>>Target.txt
这与
awk-v new_value=123-v OFS=“|”-f a.awk FS='[|>]“File2.txt FS=”|“File1.txt | sort | uniq>>Target.txt
。请您解释一下.awk在这种情况下是如何工作的。由于此人提到的是UNIX而不是默认的Linux框,awk很可能不是GNU awk。因此,这可能不是一个好的解决方案。