ansilbleのplaybookの中でpatchモジュールを使って転送したファイルにpatchをあててたのがあったのですが、なぜかパッチファイルと適用対象ファイルの改行コードがLFの時は動作するのに、CRLFだと駄目という現象が起きたので、急遽playbookの中で改行コードを変換する方法を調べてみました。
使うモジュールはこちら
replace - Replace all instances of a particular string in a file using a back-referenced regular expression. — Ansible Documentation
テスト用にこんな内容のファイルを用意します。中身は一緒で改行コードがLFのものとCRLFのものです。
$ cat org_crlf.txt
hoge
hoge
$ cat org_lf.txt
hoge
hoge
$ file hoge_*
hoge_crlf_org.txt: ASCII text, with CRLF line terminators
hoge_lf_org.txt: ASCII text
でもって、次のようなplaybookを作って実行します。
- hosts: 127.0.0.1
connection: local
strategy: debug
tasks:
- copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
with_items:
- {src: "org_crlf.txt", dest: "./hoge_crlf_to_lf.txt"}
- {src: "org_crlf.txt", dest: "./hoge_crlf_to_crlf.txt"}
- {src: "org_lf.txt", dest: "./hoge_lf_to_lf.txt"}
- {src: "org_lf.txt", dest: "./hoge_lf_to_crlf.txt"}
- name: CRLF to LF by replace
replace:
dest: "{{ item }}"
regexp: '(.*)\r\n'
replace: '\1\n'
with_items:
- "hoge_crlf_to_lf.txt"
- "hoge_lf_to_lf.txt"
- name: LF to CRLF by replace
replace:
dest: "{{ item }}"
regexp: '(.*)[^\r]\n'
replace: '\1\r\n'
with_items:
- "hoge_crlf_to_crlf.txt"
- "hoge_lf_to_crlf.txt"
やってることは、用意したファイルをコピーしてregexpでそれぞれCRLF -> LF およびその逆の変換を行なっているだけです。
結果は以下のとおり。
$ ansible-playbook test.yml
[WARNING]: Host file not found: /usr/local/etc/ansible/hosts
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [127.0.0.1] ***************************************************************
TASK [setup] *******************************************************************
ok: [127.0.0.1]
TASK [copy] ********************************************************************
changed: [127.0.0.1] => (item={u'dest': u'./hoge_crlf_to_lf.txt', u'src': u'org_crlf.txt'})
changed: [127.0.0.1] => (item={u'dest': u'./hoge_crlf_to_crlf.txt', u'src': u'org_crlf.txt'})
changed: [127.0.0.1] => (item={u'dest': u'./hoge_lf_to_lf.txt', u'src': u'org_lf.txt'})
changed: [127.0.0.1] => (item={u'dest': u'./hoge_lf_to_crlf.txt', u'src': u'org_lf.txt'})
TASK [CRLF to LF by replace] ***************************************************
changed: [127.0.0.1] => (item=hoge_crlf_to_lf.txt)
ok: [127.0.0.1] => (item=hoge_lf_to_lf.txt)
TASK [LF to CRLF by replace] ***************************************************
ok: [127.0.0.1] => (item=hoge_crlf_to_crlf.txt)
changed: [127.0.0.1] => (item=hoge_lf_to_crlf.txt)
PLAY RECAP *********************************************************************
127.0.0.1 : ok=4 changed=3 unreachable=0 failed=0
$ file hoge_*
hoge_crlf_to_crlf.txt: ASCII text, with CRLF line terminators
hoge_crlf_to_lf.txt: ASCII text
hoge_lf_to_crlf.txt: ASCII text, with CRLF line terminators
hoge_lf_to_lf.txt: ASCII text
というわけでめでたくreplaceモジュールで改行コードの変換ができたようです。
ターゲットマシンがwindowsになった時にregexpに指定している'\n'がLFとして解釈されるのか、CRLFとして解釈されるのか気にはなりますが、ちょっと今時間が無いのでここで一旦終了します。
もし知ってる方いたら教えてもらえると助かります。