gzip化されたファイルを下記の順番で処理するワンライナーなシェルスクリプトを紹介します。中間ファイルなどは生成しません。
- 解凍(gzipコマンド)
- 編集(sed / awkなど)
- 圧縮(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ファイルのみ、かつ、"-"のみが変換されていることが確認できました。