2 回答

TA貢獻1827條經驗 獲得超4個贊
每個 OP 的要求是處理大量數據(數百萬行,數 GB 數據,以及需要檢索大約 100 個項目的數據)。從技術上講,可以使用現代 bash,但這不太可能表現良好。一個更好的腳本引擎會在這里做得更好。
此處介紹了可能的 bash/awk 解決方案。它將掃描每個引用的文件一次,并一次性提取所有選定的標簽。請注意,“標簽”列表將被掃描多次,但暗示它的大小是合理的
#! /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
不用說,可以使用 Python、Perl、Javascript 或您最喜歡的文本處理工具編寫上述 5 行 awk 作業。使用示例數據集進行測試。

TA貢獻1825條經驗 獲得超6個贊
似乎每個以 開頭的條目##########總是有 6 行。在這種情況下,使用grep -A7而不是使用sed -n /##.../,/##.../p. 我想您只打印了后續標題,因為這樣更容易(至少在使用時sed)。因此,我排除了此答案中的后續標頭(grep -A6而不是grep -A7)。
grep可以給出要搜索的模式列表。這是通過-f選項完成的。模式列表可以從您的文件中生成。首先按存檔名稱(例如test365)分組,然后打印該存檔的所有模式。在這里我們習慣awk這樣做??兆止澐指裘總€存檔的模式部分。
為了防止誤報(并可能加快搜索速度),我們只搜索完整的行而不是子字符串。為了加快速度,我們設置了LC_ALL=C. 您可能還會發現它zgrep比zcat | grep.
以下腳本最多解壓縮每個存檔一次。
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自動轉換為。我不知道你的目錄結構。如果您需要不同的東西,請修改zgrep. $archive遍歷您的(分組)列表的第一列(即,每個存檔僅列出一次)。
從您的示例代碼來看,您似乎想要為每個模式生成一個單獨的文件。為此,將循環體從上方替換為
zgrep ... > /tmp/zincfound
while IFS= read -r pattern; do
grep -A6 -Fx "$pattern" /tmp/zincfound > "${pattern##* }.out"
done <<< "$patterns"
rm /tmp/zincfound
添加回答
舉報