我有 120 个 .gz 文件(每个大约 5G),带有 dos 行结尾,我的目标是将它们转换为 unix 行结尾,但我不想等待多天。
这是我目前的方法:
function conv() {
tmpfile=$(mktemp .XXXXXX)
zcat $1 > $tmpfile
dos2unix $tmpfile
gzip $tmpfile
mv $tmpfile.gz $1
}
for a in $(ls *.fastq.gz); do
echo "$a"
conv "$a" &
done
有没有办法在不拆包和重新包装的情况下修复行结尾?
答案1
无论如何,您都需要解压缩和压缩。但您不需要在每一步都保存结果。所以:
set -o noclobber
for file in *.fastq.gz; do
gzip -d < "$file" | dos2unix | pigz > "$file.new" &&
mv -- "$file.new" "$file"
done
这里使用pigz
一次利用更多处理器来进行压缩。
您还可以使用 GNU xargs
'-P
并行运行其中几个管道:
printf '%s\0' *.fastq.gz |
xargs -r0 -P4 -n1 sh -o noclobber -c '
gzip -d < "$1" | dos2unix | gzip > "$1.new" &&
mv -- "$1.new" "$1"' sh
这里并行运行 4 个。请注意gzip -d
, 、dos2unix
和gzip
在每个管道中已经并行运行(gzip
可能是管道的瓶颈)。并行运行的数量超过 CPU 数量可能会降低性能。如果您有快速的 CPU 和/或慢速的存储,您可能还会发现 I/O 是瓶颈,并且并行运行多个 CPU 实际上已经降低了性能。
当您重新压缩时,这可能是切换到不同的压缩算法的好机会,这些算法可能更适合您的需求,例如压缩得更好或更快,或者让您在独立块中随机访问数据或更快地解压缩......