首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用awk优化zgrep

使用awk优化zgrep
EN

Stack Overflow用户
提问于 2022-10-08 09:22:06
回答 2查看 74关注 0票数 1

我有一个文件列表(/c/Users/Roy/DataReceived),我想要对其进行grep一些信息,并将其存储为txt文件(/c/Users/Roy/Documents/Result)。

例如:假设我有20个文件,其中包含关于城市的不同信息,而我希望为txt文件中列出的城市提供grep信息。然后,所有这些信息将存储在另一个具有给定城市名称(NewYork.txt、Rome.txt等)的txt文件中。

以下代码正在工作:

代码语言:javascript
复制
#!/bin/bash

declare INPUT_DIRECTORY=/c/Users/Roy/DataReceived
declare OUTPUT_DIRECTORY=/c/Users/Roy/Documents/Result

while read -r city; do
  echo $city
  zgrep -Hwi "$city" "${INPUT_DIRECTORY}/"*.vcf.gz > "${OUTPUT_DIRECTORY}/${city}.txt"
done < list_of_cities.txt

然而,这个过程需要大约一周的时间才能完全运行。我的问题是,有办法只解压缩一次文件吗?比如使用awk?这将使这一过程的速度提高一倍。

此外,还有其他优化流程的方法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-08 13:36:58

下面的代码应该比解决方案快几倍:

代码语言:javascript
复制
zgrep -Hwif list_of_cities.txt /c/Users/Roy/DataReceived/*.vcf.gz |
awk -F ':' '
    NR == FNR {
        regex = regex sep "(" $0 ")"
        sep = "|"
        next
    }
    match($NF,regex) {
        city = tolower(substr($NF,RSTART,RLENGTH))
        print > ( "/c/Users/Roy/Documents/Result/" city ".txt")
    }
' list_of_cities.txt -

但是,如果您的list_of_cities.txt只包含文字城市名称(而不是regexps),那么这样做会更快:

代码语言:javascript
复制
zgrep -HwiFf list_of_cities.txt /c/Users/Roy/DataReceived/*.vcf.gz |
awk -F ':' '
    NR == FNR {
        cities[$0]
        next
    }
    {
        split($NF,words,'[^[:alnum:]_]+')
        for (c in cities)
            if (c in words) {
                city = tolower(c)
                break
            }
        print > ( "/c/Users/Roy/Documents/Result/" city ".txt")
    }
' list_of_cities.txt -

限制:如果匹配的行或文件路径可以包含:字符,则当前的awk代码将中断。

票数 1
EN

Stack Overflow用户

发布于 2022-10-08 15:27:05

我怀疑您真正需要的是下面这样的内容,假设压缩后的文件包含CSV,而城市在第三个字段中:

代码语言:javascript
复制
zcat "${INPUT_DIRECTORY}/"*.vcf.gz |
sort -t',' -k3,3 |
awk -F',' -v outDir="$OUTPUT_DIRECTORY" '
    $3 != prev {
        close(out)
        out = outDir "/" $3 ".txt"
    }
    { print > out }
'

如果文件不是CSV,那么将每个','分隔符更改为它真正的分隔符,如果城市不在第三个字段中,那么将每个3更改为它真正的字段号。

如果确实需要将输出减少到特定的城市列表,那么:

代码语言:javascript
复制
zcat "${INPUT_DIRECTORY}/"*.vcf.gz |
sort -t',' -k3,3 |
awk -F',' -v outDir="$OUTPUT_DIRECTORY" '
    NR == FNR {
        cities[$0]
        next
    }
    !($3 in cities) {
        next
    }
    $3 != prev {
        close(out)
        out = outDir "/" $3 ".txt"
    }
    { print > out }
' list_of_cities.txt -
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73995813

复制
相关文章

相似问题

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