2 回答

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超4個(gè)贊
每個(gè) OP 的要求是處理大量數(shù)據(jù)(數(shù)百萬(wàn)行,數(shù) GB 數(shù)據(jù),以及需要檢索大約 100 個(gè)項(xiàng)目的數(shù)據(jù))。從技術(shù)上講,可以使用現(xiàn)代 bash,但這不太可能表現(xiàn)良好。一個(gè)更好的腳本引擎會(huì)在這里做得更好。
此處介紹了可能的 bash/awk 解決方案。它將掃描每個(gè)引用的文件一次,并一次性提取所有選定的標(biāo)簽。請(qǐng)注意,“標(biāo)簽”列表將被掃描多次,但暗示它的大小是合理的
#! /bin/bash -uex
TAGS=data.txt
file_list=$(awk '{ print $1 }' < $TAGS | sort -u)
for f in $file_list ;
do
gz_name=${f%/}.gz
zcat $gz_name | awk -v F=$f '
# Remember tags to retrieve
!DATA && $1 == F { tags[$2] = 1 }
# OUT set to current output file, empty if item not selected
DATA && $1 == "##########" && $2 == "Name:" {
OUT = tags[$3] ? $3 ".out" : "" ;
}
OUT { print >OUT }
' $TAGS DATA=1 -
done
不用說(shuō),可以使用 Python、Perl、Javascript 或您最喜歡的文本處理工具編寫上述 5 行 awk 作業(yè)。使用示例數(shù)據(jù)集進(jìn)行測(cè)試。

TA貢獻(xiàn)1825條經(jīng)驗(yàn) 獲得超6個(gè)贊
似乎每個(gè)以 開頭的條目##########總是有 6 行。在這種情況下,使用grep -A7而不是使用sed -n /##.../,/##.../p. 我想您只打印了后續(xù)標(biāo)題,因?yàn)檫@樣更容易(至少在使用時(shí)sed)。因此,我排除了此答案中的后續(xù)標(biāo)頭(grep -A6而不是grep -A7)。
grep可以給出要搜索的模式列表。這是通過(guò)-f選項(xiàng)完成的。模式列表可以從您的文件中生成。首先按存檔名稱(例如test365)分組,然后打印該存檔的所有模式。在這里我們習(xí)慣awk這樣做??兆止?jié)分隔每個(gè)存檔的模式部分。
為了防止誤報(bào)(并可能加快搜索速度),我們只搜索完整的行而不是子字符串。為了加快速度,我們?cè)O(shè)置了LC_ALL=C. 您可能還會(huì)發(fā)現(xiàn)它zgrep比zcat | grep.
以下腳本最多解壓縮每個(gè)存檔一次。
awk -v prefix='########## Name: ' '
{a[$1]=a[$1] "\n" prefix $2}
END {for (k in a) print k a[k] "\0"}
' /path/to/your/list.txt |
while IFS=$'\n' read -r -d '' archive patterns; do
LC_ALL=C zgrep -A6 -Fxf <(printf %s "$patterns") "${archive/\//.gz}"
# TODO do something with the output for this archive
done
在上面的腳本中,我test365/從您的列表test365.gz自動(dòng)轉(zhuǎn)換為。我不知道你的目錄結(jié)構(gòu)。如果您需要不同的東西,請(qǐng)修改zgrep. $archive遍歷您的(分組)列表的第一列(即,每個(gè)存檔僅列出一次)。
從您的示例代碼來(lái)看,您似乎想要為每個(gè)模式生成一個(gè)單獨(dú)的文件。為此,將循環(huán)體從上方替換為
zgrep ... > /tmp/zincfound
while IFS= read -r pattern; do
grep -A6 -Fx "$pattern" /tmp/zincfound > "${pattern##* }.out"
done <<< "$patterns"
rm /tmp/zincfound
添加回答
舉報(bào)