目的
何らかの作業対象のテキストやファイルがあり、指定した行ごとに任意の文字列を挿入したい場合を想定。
具体的には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