🗂

[Shell]指定数でのCSVファイル分割とディレクトリ作成

2020/12/13に公開
  • 業務でShellで大きいCSVファイルを扱う場合がある。
  • その際に、事前に分割フォルダ分けを行うことで、扱いやすくなることがある。
  • そのため今回は、Shellで行数に応じてファイル分割やフォルダ分類を行う方法を記録する。

結果

  • 以下、実行前のディレクトリ構造。
    • sample.csvは行数100のデータ
.
├── sample.csv
├── main.sh
  • 以下、main.shの記述。
#!/bin/sh
set -e

# ファイル名
[ ! -e "$1" ] && exit 1 || datafile="$1"
# 拡張子除外
filename="${datafile%.*}"
# 行数取得
row=$(awk -F ',' 'END {print NR}' $datafile)
# 分割数
sep="$2"
# 作成ディレクトリ数
dir_cnt=$(awk -v row="$row" -v sep="$sep" 'BEGIN {
	i=row/sep
	printf("%d\n",i+=i<0?0:0.999)
	}
	'
)
# フォルダ作成
seq -f "${filename}_%01.0f" 1 ${dir_cnt} |
xargs mkdir -p
# ファイル分割
split -l ${sep} -a 2 $datafile "${filename}_"
# ファイル移動
count=1
for i in `find . -type f -name "${filename}_*" | sort`
do
	mv $i "${filename}_${count}/${i//_*/_${count}}.csv"
	let count++
done

exit 0
  • 以下で実行。
# sh main.sh 対象データ 分割数
sh main.sh sample.csv 25
  • 実行後、以下のディレクトリ構造になっていることを確認。
.
├── main.sh
├── sample.csv
├── sample_1
│   ├── sample_1.csv
├── sample_2
│   ├── sample_2.csv
├── sample_3
│   ├── sample3.csv
├── sample_4
│   ├── sample4.csv

補足

作成ディレクトリ数

  • 作成ディレクトリ数の計測の際に、awkを利用する。
  • その際に意識した点は以下。
    • 行数と分割数を変数として渡す。
      • awkの-vオプションを利用して安全かつ扱いやすくしておく。
    • 切り上げ処理
      • 100/15のような小数の場合、ディレクトリ作成が正常に行われないため。
      • printf処理で切り上げして整数にしておく。

ファイル分割と移動

  • 分割と移動処理は、それぞれ分けて行う。
  • その際に意識した点は以下。
    • 拡張子付与はmvで行う。
      • splitでの拡張子付与(--additional-suffix)は、Mac等ではデフォルトではないため。

参考

Discussion