見出し画像

指定した文字列を含む行が連続した時に、その最初の行以外を削除するBashスクリプト

↑文章で説明するとわけわからん。超限定的でマニアックな用途すぎるので
誰もサンプルコードを書いてる人がいない。
ので、自分でスクリプトを書いた。自分しか使う人はいないと思う。

RPGツクールMVでシナリオテキストを抜き出した時に
例えばa.txt(↓参照)というテキストがあったときに、
N[*]が連続するのがうっとうしいので2連続目以降は削除したい。

つまり、

処理前
======a.txt======
\N[1]:
会話1
\N[1]:
会話2
\N[2]:
会話3
\N[2]:
会話4
\N[2]:
会話5
\N[3]:
会話6
\N[1]:
会話7

のテキストを

処理後
======a_out.txt======
\N[1]:
会話1

会話2
\N[2]:
会話3

会話4

会話5
\N[3]:
会話6
\N[1]:
会話7

をこんな感じに処理したい


書いたスクリプトがこれ

======ejectN.sh======
#!/bin/bash

CRLF=$'\r\n'
PRE="default"

if [ $# != 1 ]; then
   echo "arg error: set file name"
   exit 1
else
   OUT=$(echo $1 | awk -F "." '{print $1 "_out.txt"}')
   echo "outputfile is" $OUT
fi

while read line
do
 if [[ $line == *"N["* ]]; then
   if [ $line = $PRE ]; then
     echo $CRLF >> $OUT
   else
     echo $line >> $OUT
   fi
   PRE=$line
 else
   echo $line >> $OUT
 fi
done < $1

======ejectN.sh解説======
使い方
$./ejectN.sh a.txt

中身
#!/bin/bash

#Windwosの改行コードを宣言
CRLF=$'\r\n' 
#指定行の連続判定用の変数。初期値は適当。
PRE="default"

#引数が設定されていなければError
if [ $# != 1 ]; then
   echo "arg error: set file name"
   exit 1
else
#処理後のデータの名前を決定 例えばa.txtを変換したいなら出力ファイルはa_out.txtになる
   OUT=$(echo $1 | awk -F "." '{print $1 "_out.txt"}')
   echo "outputfile is" $OUT
fi

#引数$1で指定したファイルを一行ずつ読み込む
while read line
do
#もし読み込んだ一行に "N[" が含まれていた場合、 
 if [[ $line == *"N["* ]]; then
#"N["連続しているかどうかの判定
   if [ $line = $PRE ]; then
#連続していた場合、改行だけを出力ファイルにリダイレクト
     echo $CRLF >> $OUT
   else
#連続していなかった場合、その一行をそのまま出力ファイルにリダイレクト
     echo $line >> $OUT
   fi
#読み込んだ行を比較用に保存する(バッファ)
   PRE=$line
#もし読み込んだ一行に "N[" が含まれていない場合、   
 else
#その一行をそのまま出力ファイルにリダイレクト
   echo $line >> $OUT
 fi
done < $1

実行結果は上の例で書いた通り。

これを実行したところ先日記事を書いた文字化けにはまったので


備忘録として残しておく。


すべてのテキストファイルを一括でスクリプト処理したいときは 


$ find *.txt | xargs -I {} ./ejectN.sh {}

いいなと思ったら応援しよう!