在bash脚本中连接不同压缩类型的文件的最有效方法是什么?

时间:2013-03-08 22:30:01

标签: bash cat built-in

我现在已经多次遇到过这种需求,我很惊讶我找到一种“最佳”方法连接不同压缩类型的文件是多么困难。

例如,我有一个包含文件content1content2.bz2content3.gz的目录。如果我想对所有文件执行相同的操作,我必须首先检查它们是正确解压缩它们,解压缩它,然后执行我的操作。

我已经编写了一个脚本来以“智能”的方式处理串联。

#! /bin/bash
# Smart Cat
# usage smcat <file|file*>

for file in $@; do
    end=${file##*.}
    if [[ $end == 'bz2' ]] ; then
        bzcat $file
    elif [[ $end == 'gz' ]] ; then
        gzcat $file
    else
        cat $file
    fi
done

看起来很愚蠢没有内置的方法来处理所有不同的压缩类型。或者在那里,我还没有找到它?感谢大家的帮助!

2 个答案:

答案 0 :(得分:1)

可能没有一种内置方法可以处理不同的压缩类型。如果您不想依赖文件扩展名来确定压缩类型,可以使用file命令,例如。

file test.bz2   
test.bz2: bzip2 compressed data, block size = 900k

答案 1 :(得分:1)

使用GNU Tar的自动压缩标志

如果您主要处理tarball,可以使用GNU tar的自动压缩标记解决部分问题,该标记表示:

 -a, --auto-compress
       use archive suffix to determine the compression program

这可以处理bz2和gz扩展,但可能会因为更多异国情调而失败。例如:

tar xvfz "$filename"

将在 somefile.tar.gz somefile.tar.bz2 上使用相同的工具。

使用/usr/bin/file进行身份识别

文件实用程序通常会在grep或glob模式的帮助下为您提供正确的文件类型。例如:

$ file foo*
foo:     ASCII text
foo.bz2: bzip2 compressed data, block size = 900k
foo.gz:  gzip compressed data, was "bar", from Unix, last modified: Fri Mar  8 17:33:48 2013

您可以使用case语句来简化这些文件的工作,无论是迭代文件glob还是使用"$@"的位置参数。无论哪种方式,这个例子应该有所帮助:

for file in foo*; do
    case `file "$file"` in
        *ASCII*) cat   "$file" ;;
         *gzip*) zcat  "$file" ;;
          *bz2*) bzcat "$file" ;;
    esac
done