LoginSignup
0
1

More than 5 years have passed since last update.

複数のテキストファイルに同じ修正を適用する

Last updated at Posted at 2016-08-05

似たような複数のテキストファイルに対して、全く同じ修正を適用する。設定ファイルの類でたまにそういう作業が発生する事があります。最近だと巷で噂の httpoxy 対策とか。Apacheの .htaccess にproxy削除の1行を追加したいんだけど、サイトを大量を抱えていて、一々エディタで開いて追記して回るのも大変だ〜、なんて話もあるかと思います。というか私がそんな作業に遭遇しました…

要点

手作業は面倒だし、間違えるのが怖い。そこで自動化を図る。

  • patch コマンドを利用。どのファイルでも同じ位置へ適用する作業でないと、ちょっと危ないかも知れませんが。今回のような話であれば大丈夫です。
  • 確認には「差分の一致」を調べる事で、人間の注意力が必要な場面を極力減らす。

テキストの追記や修正は sed を使っても可能ですが、少々面倒なんですよね。それだけに応用範囲も広いんですが。今回は、Linux初心者だと使う機会が少ない(と思う) patch コマンドを使いました。古くからUNIX系OSを使っているパワーユーザにとっては、既に良く御存知の手順です。

詳細

作業対象

次の3つのファイルを作業対象とします。

$ for pf in hoge tara ponn; do echo ===== htaccess-$pf =====; cat htaccess-$pf; echo; done
===== htaccess-hoge =====
<VirtualHost *:80>
    ServerAdmin webmaster@hoge.example.com
    DocumentRoot /www/docs/hoge.example.com
    ServerName hoge.example.com
    ErrorLog /var/log/httpd/hoge.example.com/error_log
    TransferLog /var/log/httpd/hoge.example.com/access_log

    # sample comment, first
</VirtualHost>

===== htaccess-tara =====
<VirtualHost *:80>
    ServerAdmin webmaster@tara.example.com
    DocumentRoot /www/docs/tara.example.com
    ServerName tara.example.com
    ErrorLog /var/log/httpd/tara.example.com/error_log
    TransferLog /var/log/httpd/tara.example.com/access_log

    # sample comment, first
    # sample comment, second
</VirtualHost>

===== htaccess-ponn =====
<VirtualHost *:80>
    ServerAdmin webmaster@ponn.example.com
    DocumentRoot /www/docs/ponn.example.com
    ServerName ponn.example.com
    ErrorLog /var/log/httpd/ponn.example.com/error_log
    TransferLog /var/log/httpd/ponn.example.com/access_log

    # sample comment, first
    # sample comment, second
    # sample comment, third
</VirtualHost>

これの「所定の位置」に、次の内容を追加します。

# 2016.08.05.Fri (httpoxy)
RequestHeader unset Proxy

手順

最初のファイルを手作業で修正

$ vi htaccess-hoge
$ svn di --diff-cmd diff -x -U2
Index: htaccess-hoge
===================================================================
--- htaccess-hoge       (revision 3)
+++ htaccess-hoge       (working copy)
@@ -6,4 +6,7 @@
     TransferLog /var/log/httpd/hoge.example.com/access_log

+    # 2016.08.05.Fri (httpoxy)
+    RequestHeader unset Proxy
+
     # sample comment, first
 </VirtualHost>

差分を取り出す

$ svn di --diff-cmd diff -x -U0 >htaccess.diff
$ cat htaccess.diff
Index: htaccess-hoge
===================================================================
--- htaccess-hoge (revision 3)
+++ htaccess-hoge (working copy)
@@ -7,0 +8,3 @@
+    # 2016.08.05.Fri (httpoxy)
+    RequestHeader unset Proxy
+

他のファイルに適用

$ for pf in tara ponn; do patch htaccess-$pf <htaccess.diff; done
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|Index: htaccess-hoge
|===================================================================
|--- htaccess-hoge      (revision 3)
|+++ htaccess-hoge      (working copy)
--------------------------
Patching file htaccess-tara using Plan A...
Hunk #1 succeeded at 8.
done
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|Index: htaccess-hoge
|===================================================================
|--- htaccess-hoge      (revision 3)
|+++ htaccess-hoge      (working copy)
--------------------------
Patching file htaccess-ponn using Plan A...
Hunk #1 succeeded at 8.
done

パッチファイルのヘッダに示されているファイル名と、指示した適用先ファイル名が異なっているので報告してきますが、無視!

確認

確認は大事です。適用した全ファイルの差分が、最初に手作業で実施した htaccess-hoge の差分と一致する事を確認します。

で、その差分の取り方に一工夫。詳細は下記。bashのプロセス置換を利用しています。

$ for pf in tara ponn; do diff -sU0 <(tail -n+5 htaccess.diff) <(svn di --diff-cmd diff -x -U0 htaccess-$pf | tail -n+5) --label "htaccess-hoge の差分" --label "htaccess-$pf の差分"; done
Files htaccess-hoge の差分 and htaccess-tara の差分 are identical
Files htaccess-hoge の差分 and htaccess-ponn の差分 are identical

コマンドの意味

長いですが、丁寧に追えば理解できるでしょう。

まず diff -sU0 <FILE1> <FILE2> --label <LABEL1> --label <LABEL2> について。単純な、diffコマンドのオプション指定です。何の捻りもありませんが、ここで下記のように工夫しました:

  1. <FILE1> <FILE2> の部分に、差分の中の必要部分を取り出して与えています。
  2. <LABEL1> <LABEL2> の部分には「差分なんだよ」を意味する言葉を置いています。これで表示結果が見易くなります。
  3. diff のオプション -s について。一致した時には一致した事を表す文言を表示します。エビデンスを残す必要がある場合には非常に助かります。

<FILE1> には、最初の差分 htaccess.diff の内、ファイル名を表している部分を削除して与えています。

$ cat htaccess.diff
Index: htaccess-hoge
===================================================================
--- htaccess-hoge       (revision 3)
+++ htaccess-hoge       (working copy)
@@ -7,0 +8,3 @@
+    # 2016.08.05.Fri (httpoxy)
+    RequestHeader unset Proxy
+
$ tail -n+5 htaccess.diff
@@ -7,0 +8,3 @@
+    # 2016.08.05.Fri (httpoxy)
+    RequestHeader unset Proxy
+

<FILE2> の部分も同様ですね。Subversionで取得した差分の内、ファイル名を表している部分を削除して与えています。

$ svn di --diff-cmd diff -x -U0 htaccess-tara
Index: htaccess-tara
===================================================================
--- htaccess-tara       (revision 3)
+++ htaccess-tara       (working copy)
@@ -7,0 +8,3 @@
+    # 2016.08.05.Fri (httpoxy)
+    RequestHeader unset Proxy
+
$ svn di --diff-cmd diff -x -U0 htaccess-tara | tail -n+5
@@ -7,0 +8,3 @@
+    # 2016.08.05.Fri (httpoxy)
+    RequestHeader unset Proxy
+

最後は、これを対象ファイルの分だけループします。ループの方法やファイル名の与え方などは、状況に合わせて調整して下さい。

不要ファイルを削除

問題無く修正できた事を確認したら、不要なファイルを削除します。

  • 最初の差分ファイル
  • patchコマンドが自動生成したバックアップファイル

バージョン管理ツールを使用していれば、これらは管理外のファイルとして現れます。それを捕まえれば、ここも自動化できます。

$ svn st | awk '/^\?/ {print $2}' | xargs rm -v
htaccess-ponn.orig
htaccess-tara.orig
htaccess.diff

最後にSubversionにcommitすれば完了です。ここまで、手作業での修正は最初のファイルだけでした。後は自動。やった :thumbsup:

0
1
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
0
1