我有一个文件列表(/c/Users/Roy/DataReceived),我想要对其进行grep一些信息,并将其存储为txt文件(/c/Users/Roy/Documents/Result)。
例如:假设我有20个文件,其中包含关于城市的不同信息,而我希望为txt文件中列出的城市提供grep信息。然后,所有这些信息将存储在另一个具有给定城市名称(NewYork.txt、Rome.txt等)的txt文件中。
以下代码正在工作:
#!/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?这将使这一过程的速度提高一倍。
此外,还有其他优化流程的方法吗?
发布于 2022-10-08 13:36:58
下面的代码应该比解决方案快几倍:
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),那么这样做会更快:
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代码将中断。
发布于 2022-10-08 15:27:05
我怀疑您真正需要的是下面这样的内容,假设压缩后的文件包含CSV,而城市在第三个字段中:
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更改为它真正的字段号。
如果确实需要将输出减少到特定的城市列表,那么:
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 -https://stackoverflow.com/questions/73995813
复制相似问题