LoginSignup
1
0

More than 3 years have passed since last update.

指定行ごとに文字列を挿入し、最終行にも文字列を挿入する

Last updated at Posted at 2020-03-23

目的

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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0