Gzip化されたファイルの末尾行を編集する方法

gzip化されたファイルを下記の順番で処理するワンライナーなシェルスクリプトを紹介します。中間ファイルなどは生成しません。

  1. 解凍(gzipコマンド)
  2. 編集(sed / awkなど)
  3. 圧縮(gzip)

下記のコマンドになります。

# 末尾行の"-"を空白""に変換
$ gzip -d -c sample.csv.gz | sed -e "$ s/-//g" | gzip -c > new_sample.csv.gz

# 末尾行の"-"を削除
$ gzip -d -c sample.csv.gz | sed -e sed -e '${/-/d;}' | gzip -c > new_sample.csv.gz

※参考にしたStackOverflow(https://unix.stackexchange.com/questions/552756/edit-the-contents-of-a-gen-gz-file-using-linux-awk-or-sed

末尾行に邪魔な文字列を含むファイルを作成してGzip化

末尾行に邪魔な文字("-")が含まれているファイルを作成します。

$ echo -e '1,2,3\n4,5,6\n-' | gzip -c > sample.csv.gz

$ zcat sample.csv.gz
1,2,3
4,5,6
-

末尾行の処理

解凍して、編集して、圧縮するというのを素直に実行していきます。

# 解凍して標準出力
$ gzip -d -c sample.csv.gz
1,2,3
4,5,6
-

# 標準出力から末尾行の"-"を空白に変換
$ gzip -d -c sample.csv.gz | sed -e '$ s/-//g'
1,2,3
4,5,6

# (おまけ)標準出力から末尾行の"-"を削除
$ gzip -d -c sample.csv.gz | sed -e '${/-/d;}'
1,2,3
4,5,6

# 末尾行が空白に置換された標準出力を圧縮する
$ gzip -d -c sample.csv.gz | sed -e "$ s/-//g" | gzip -c > new_sample.csv.gz

# zcat new_sample.csv.gz
1,2,3
4,5,6

sedコマンドを変更すれば、末尾行に限らず応用ができるかと思います。

(おまけ)特定ディレクトリ内のすべてのファイルに対して処理

上記で作成したコマンドを、特定のディレクトリに含まれるすべてのgzファイルに対して実行するシェルスクリプトを作成します。

inputDir=$1
outputDir=$2

if [ $# != 2 ]; then
    echo 'Erro: two arguments are required:' $*
    exit 1
else
    mkdir -p ${outputDir}
fi

echo ' input dir : '${inputDir}
echo 'output dir : '${outputDir}
echo ''

numFile=`find ./${inputDir} -type f -name '*.gz' | wc -l`

idx=1

for file in `find ./${inputDir} -type f -name '*.gz'`; do
    echo ${idx}/${numFile} : ${file}
    outputFile=`basename ${file}`
    gzip -d -c ${file} | sed -e "$ s/-//g" | gzip -c > ./${outputDir}/${outputFile}
    idx=$((idx+1))
done

入力となるディレクトリ名と、変換後のファイルを出力するディレクトリ名を引数として受け取ります。

findコマンドで対象のファイルをリストアップして、for文で各ファイルを処理します。

上記のbashスクリプトを実行する

# ダミーデータの作成
$ echo -e '1,2,3\n4,5,6\n-' | gzip -c > input/sample1.csv.gz
$ echo -e '1,2,3\n4,5,6\n@@@' | gzip -c > input/sample2.csv.gz
$ echo -e '1,2,3\n4,5,6\n7,8,9' > input/sample3.csv

#実行
$ bash convert.sh input/ output
 input dir : input/
output dir : output

1/2 : ./input/sample1.csv.gz
2/2 : ./input/sample2.csv.gz

$ zcat ./output/sample1.csv.gz
1,2,3
4,5,6

$ zcat ./output/sample2.csv.gz
1,2,3
4,5,6
@@@

gzファイルのみ、かつ、"-"のみが変換されていることが確認できました。

  • この記事を書いた人

たかさん

犬と暮らすクラウドエンジニア。GCPが好きだけど良く触るのはAWSとAzureです。

-コマンド
-,