2013-05-10

indented-text handling by using echo and here-document of bash on os x lion

KeyRemap4MacBookの調整の時に、動的に替わるxmlや複雑なxmlを作る事が多くなって来た。一般に、xmlが多量になるとインデント(indent)を確実にしないと、見通しが極度に低下する。更にKeyRemap4MacBookの特殊性として、「<autogen>タブ階層構造」と「<item>タブの階層構造」とが別々に意味を持つので、正しくインデントの必要性が高まって来た。

これらの「インデントされたテキスト(indented text)」を生成するときには、エスケープ・シークエンス(escape sequences)による出力 ;
  • 「エスケープ・シークエンスのオプションの付いたエコー・コマンド」
    • echo -e "\tHoge.$JJJ hoge\n"
を使っていた。しかし、量が増えて来たり、変数(variable, $JJJ)が入ってくると、作り間違えが急造して、修正が大変になってしまう。

そこで、不得意な「ヒア・ドキュメント(here document)」を使った具体例、echo_and_here-documentを作製したので、以下に説明する。なお、変数(variable, $JJJ)の処理は最後に触れます。

u1@mmX75:~/bin $ cat echo_and_here-document
#!/bin/bash

ex5() {

# EXAMPLE 5: basic "here document" wrapped in function, ex5    ###########
JJJ=$((JJJ+1))
cat <<EOF

<!-- EXAMPLE $JJJ: basic "here document" wrapped in function, ex5 -->
    <abc>
        efg, hij
    </abc>
   
EOF

}

################ Main ####################################################
echo  "$(basename $0): start"


# EXAMPLE 1: direct "echo with -e option" ################################
JJJ=1
echo -e "\n<!-- EXAMPLE $JJJ: simple \"echo with -e option\"\c"
echo -e " -->\n\t<abc>\n\t\tefg, hij\n\t</abc>"

# EXAMPLE 2: basic "here document" #######################################
JJJ=$((JJJ+1))
cat <<EOF

<!-- EXAMPLE $JJJ: basic "here document" -->
    <abc>
        efg, hij
    </abc>
   
EOF

# EXAMPLE 3: command substitution includes "here document" ###############
JJJ=$((JJJ+1))
ex3="$(
cat <<EOF

<!-- EXAMPLE $JJJ: "here document" included
                 by "command substitution:\$(...)"
                 and saved to variable, \$ex3.-->
    <abc>
        efg, hij
    </abc>
   
EOF
)"
echo "$ex3"

# EXAMPLE 4: basic "here document" redirect file, ex4. ###################
JJJ=$((JJJ+1))
cat <<EOF > ex4

<!-- EXAMPLE $JJJ: basic "here document" redirects to file, ex4 -->
    <abc>
        efg, hij
    </abc>
   
EOF
cat ex4
rm -f ex4

# EXAMPLE 5: basic "here document" redirect file in function ex5. ########
ex5 # just call function, ex5


# EXAMPLE 6: basic "here document" redirect file
#                 in external function ex6 at myUtuities ########
. myUtilities
ex6 # just call function, ex6

echo ""
echo "============= myUtilities ====================="
cat $HOME/bin/myUtilities | sed -e "s/^/contents: /"
echo "==============================================="

################ Main ####################################################
u1@mmX75:~/bin $


この実行結果は;

u1@mmX75:~ $ echo_and_here-document
echo_and_here-document: start

<!-- EXAMPLE 1: simple "echo with -e option" -->
    <abc>
        efg, hij
    </abc>

<!-- EXAMPLE 2: basic "here document" -->
    <abc>
        efg, hij
    </abc>
   

<!-- EXAMPLE 3: "here document" included
                 by "command substitution:$(...)"
                 and saved to variable, $ex3.-->
    <abc>
        efg, hij
    </abc>
   

<!-- EXAMPLE 4: basic "here document" redirects to file, ex4 -->
    <abc>
        efg, hij
    </abc>
   

<!-- EXAMPLE 5: basic "here document" wrapped in function, ex5 -->
    <abc>
        efg, hij
    </abc>
   

<!--
    EXAMPLE 6: basic "here document" wrapped
    in function, ex6() at external file, myUtilities
-->   
    <abc>
        efg, hij
    </abc>
   

============= myUtilities =====================
contents: #!/bin/bash
contents:
contents: ex6(){
contents:
contents: # EXAMPLE 6: basic "here document" wrapped in function, ex6 at myUtulities    ###########
contents: JJJ=$((JJJ+1))
contents: cat <<EOF
contents:
contents: <!--
contents:     EXAMPLE $JJJ: basic "here document" wrapped
contents:     in function, ex$JJJ() at external file, myUtilities
contents: -->   
contents:     <abc>
contents:         efg, hij
contents:     </abc>
contents:    
contents: EOF
contents: }
===============================================
echo_and_here-document: end
u1@mmX75:~ $

使った感想としては、利用目的に応じて;
  • 超簡単なら、EXAMPLE1
  • 簡単なら、EXAMPLE2
  • 繰り返しの利用なら、EXAMPLE3
  • ファイルとして保存なら、EXAMPLE4
  • 開発途中のファイルなら関数が使いよいかも、 EXAMPLE5
  • 開発が終わって、共通なユーティリティ・ファイルにするのもよい、EXAMPLE6
といった感じです。KeyRemap4MacBook関係では、圧倒的にEXAMPLE5らしそうです。

最後に変数(variable, $JJJ)の定義と演算ですが;
  • 数値代入:JJJ=5
  • 数値演算:KKK=$((JJJ*2))
実例;

u1@mmX75:~ $ JJJ=5
u1@mmX75:~ $ KKK=$((JJJ*2))
u1@mmX75:~ $ echo -e "\tJJJ=$JJJ, KKK=JJJ*2=$KKK"
    JJJ=5, KKK=JJJ*2=10
u1@mmX75:~ $

感想
  •  自信を持って、明確にヒア・ドキュメントを使えるようになった。
  • 「echo -e」の解説; 下記の本の「p71,72」が簡明で、その様に動作した。
    • Arnold Robbins, "bash Pocket Reference", O'REILLY, 2010
    •  ISBN: 978-1-449-38788-4 
  • 動作環境
    • Mac mini (mid 2011), Lion 10.7.5
    • bash --version
      • GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
____
この記事の履歴
  1. 開始 2013-05-10(金) 14:57:11 
  2. 修正 2013-05-12(日) 02:30:18 
  3. 追加 2013-05-13(月) 17:11:01 EXAMPLE6

0 件のコメント:

コメントを投稿

注目の投稿

Terminalでの、なんちゃってViモドキ

近頃、ようやくKarabiner-Elementsに慣れてきたので、 Terminalで動作する「擬似Vi-Mode」を作って見たので、ご紹介します。 『概要』 「擬似Vi-Mode」の所以は、方向キー「←↓↑→」を通常の「hjkl」ではなくて「jkil」としました。これ...