簡體   English   中英

合並排序gzip壓縮文件

[英]Merge sort gzipped files

我有40個文件,每個2GB,存儲在NFS架構上。 每個文件包含兩列:數字ID和文本字段。 每個文件都已經過排序和gzip壓縮。

如何合並所有這些文件,以便生成的輸出也被排序?

我知道sort -m -k 1應該為未壓縮的文件做技巧,但我不知道如何直接使用壓縮文件。

PS:我不想要將文件解壓縮到磁盤,合並它們以及再次壓縮的簡單解決方案,因為我沒有足夠的磁盤空間。

這是進程替換的用例。 假設您有兩個要排序的文件, sorta.gzsortb.gz 您可以使用<(...) shell運算符為gunzip -c FILE.gz輸出以對這兩個文件進行排序:

sort -m -k1 <(gunzip -c sorta.gz) <(gunzip -c sortb.gz) >sorted

進程替換使用表示該命令輸出的文件名替換命令,並且通常使用命名管道或/dev/fd/...特殊文件實現。

對於40個文件,您將需要動態創建具有許多進程替換的命令,並使用eval執行它:

cmd="sort -m -k1 "
for input in file1.gz file2.gz file3.gz ...; do
    cmd="$cmd <(gunzip -c '$input')"
done
eval "$cmd" >sorted       # or eval "$cmd" | gzip -c > sorted.gz
    #!/bin/bash

    FILES=file*.gz               # list of your 40 gzip files
                                 # (e.g. file1.gz ... file40.gz)

    WORK1="merged.gz"            # first temp file and the final file
    WORK2="tempfile.gz"          # second temp file

    > "$WORK1"                   # create empty final file
    > "$WORK2"                   # create empty temp file

    gzip -qc "$WORK2" > "$WORK1" # compress content of empty second
                                 # file to first temp file

    for I in $FILES; do
        echo current file: "$I"
        sort -k 1 -m <(gunzip -c "$I") <(gunzip -c "$WORK1") | gzip -c > "$WORK2"
        mv "$WORK2" "$WORK1"
    done

使用bash globbing(文件* .gz)或40個文件名列表(用白色空格分隔)填寫$ FILES最簡單的文件列表。 $ FILES中的文件保持不變。

最后,80 GB數據在$ WORK1中壓縮。 處理此腳本時,沒有未壓縮的數據寫入磁盤。

在單個管道中添加不同風格的多文件合並 - 它需要$OUT/uniques uniques中的所有(預先排序的)文件,對它們進行排序合並並壓縮輸出,因為它的速度使用lz4:

find $OUT/uniques -name '*.lz4' |
  awk '{print "<( <" $0 " lz4cat )"}' |
  tr "\n" " " |
  (echo -n sort -m -k3b -k2 " "; cat -; echo) |
  bash |
  lz4 \
> $OUT/uniques-merged.tsv.lz4

確實有zgrep和其他常用實用程序可以使用壓縮文件,但在這種情況下,您需要對未壓縮數據進行排序/合並並壓縮結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM