目的
何らかの作業対象のテキストやファイルがあり、指定した行ごとに任意の文字列を挿入したい場合を想定。
具体的にはSQLでの指定行でのCOMMIT。
恐らく各RDBMSのCLIでは便利な機能があると思いますが、機械的に実行してしまいたい時に利用します。
注意
本来はある一連の作業がすべて終わった場合に明示的にCOMMITすべきであり、意図しない変更の場合のROLLBACKが大変になるリスクがあります。
単純INSERTであっても、変更を元に戻せる安全なUPDATE文やDELETE文を用意しておいた方が良いです。
shellの動作について
改行コード込みの特定文字列をshell実行時引数で指定したかったのですが、今回はコードに直書き(ハードコーティング)しています。
スクリプト
説明用の桁数揃えシーケンスファイルの作成
# !/usr/bin/env bash
# 4桁の数字を0埋めで0001 - 1500まで出力
seq -f "%04g" 1500 > TARGET.txt
head TARGET.txt
# 0001
# 0002
# 0003
# 0004
# 0005
# 0006
# 0007
# 0008
# 0009
# 0010
tail TARGET.txt
# 1491
# 1492
# 1493
# 1494
# 1495
# 1496
# 1497
# 1498
# 1499
# 1500
insert_break
# !/usr/bin/env bash
# 使用方法:
# TARGET.txtに200行ごとに文字列「COMMIT;\n」を挿入
# sh insert_break.sh TARGET.txt 200
temp_file=$(mktemp)
basename_excluding_ext=`echo ${1} | sed 's/\.[^\.]*$//'`
edited_txt=${basename_excluding_ext}.edited.txt
cat ${1} | awk '{print $0} NR%'${2}'==0 {printf "COMMIT;\r\n"}' > ${temp_file}
# 作業後のファイル名を変更する
mv ${temp_file} ${edited_txt}
# 指定ファイルの行数が指定行数で割り切れない場合、最終行に同一の文字列を挿入する
if [ $(( `wc -l ${1} | awk '{print $1}'` % ${2} )) != 0 ];
then
sed -i -e '$ a COMMIT;' ${edited_txt}
fi
使用例
# 200行ごとに特定文字列(例 COMMIT;\n)の挿入
sh insert_break.sh TARGET.txt 200
# 確認
# 200行付近
cat TARGET.edited.txt | head -n 204 | tail -n 10
# 0195
# 0196
# 0197
# 0198
# 0199
# 0200
# COMMIT;
# 0201
# 0202
# 0203
# 最終行付近
tail TARGET.edited.txt
# 1492
# 1493
# 1494
# 1495
# 1496
# 1497
# 1498
# 1499
# 1500
# COMMIT;
参考URL
n行ごとに改行を挿入するシェルスクリプト
bashで四則演算(+-×÷)や割り算のあまり(剰余)を求めるような簡単な計算をする | 俺的備忘録 〜なんかいろいろ〜
bashの変数展開によるファイル名や拡張子の取得 - Qiita