トップ 追記

Days of Speed

過ぎゆく日々を書こう。忘れっぽい未来の自分のために

お知らせ(2012/12/30): 野方のGmailアカウントからスパムメールが送信された件については「#GmHackHigai」タグにまとめています。


2013-05-07 [長年日記]

_ VeeWeeを使わずWheezyのVagrantのBoxを作る

Vagrantといえば今更だけど、特殊な状況があって環境を用意する必要がありVirtualBox単体で作ってもよかったのだけれど、ちょっと慣れておこうかと思ってVagrantをインストールしてみた。 しかし、Vagrantbox.esにプレーンなDebian WheezyのboxがなかったのでBase boxから作ってみたのでメモ。

使用したVagrantは、debianパッケージもありますがgemからインストールしています。バージョンはVagrantは1.0.7。Virtualboxは4.2.12です。

参考

ベース仮想マシンの作成

Vagrantのドキュメントに書かれている仮想マシンの構成に従って作成します。

ハードディスク 40GB以上
メモリ なるべく少なく(360MB)
オーディオ・USB 無効
ネットワーク NAT
  • 最終的なboxサイズは500MB以下にする。

ということで、こんな感じで作成しました。

  • OSタイプ: Debian
  • メモリ: 384MB
  • VRAM: 9MB
  • HDD: 50GB

GUIから普通に作ってもよいですが、コマンドラインから作るとこんな感じ。 (というかコマンドラインから作る必要性はまったくなく、ちょっと書いてみたかっただけなので無理にこれを使うことはないです。)

# Debianマシンの設定
vboxmanage createvm --name vagrant-debian-wheezy --ostype Debian --register
vboxmanage modifyvm vagrant-debian-wheezy --memory 384 --vram 9 --rtcuseutc on
# ストレージコントローラの設定
vboxmanage storagectl vagrant-debian-wheezy --name IDE --add ide
vboxmanage storagectl vagrant-debian-wheezy --name SATA --add sata --sataportcount 1
# HDDを作成(50GB)
vboxmanage createhd --filename ~/VirtualBox\ VMs/vagrant-debian-wheezy/vagrant-debian-wheezy.vdi --size 51200
# HDDとCDをマウント
vboxmanage storageattach vagrant-debian-wheezy --storagectl IDE --port 1 --device 0 --type dvddrive --medium ~/debian-7.0.0-i386-CD-1.iso
vboxmanage storageattach vagrant-debian-wheezy --storagectl SATA --port 0 --device 0 --type hdd --medium ~/VirtualBox\ VMs/vagrant-debian-wheezy/vagrant-debian-wheezy.vdi
# ブートデバイスの変更
vboxmanage modifyvm vagrant-debian-wheezy --boot1 dvd --boot2 disk --boot3 none --boot4 none

Debianのインストール

VirtualBoxにWheezyをインストールします。インストールは通常のインストールで構いませんが、サイズを小さくするため「ソフトウェアの選択」のチェックをすべて外してインストールします。また、個人的にはrootは不要なので「rootのパスワード」の入力画面でパスワードを空にしてrootを無効にしています。

ネットワークとアカウントは、Vagrantのドキュメントにしたがって設定します。

ホスト名 vagrant-[os名] 例) vagrant-debian-lenny
ドメイン vagrantup.com
Rootパスワード(rootを無効にするなら不要) vagrant
メインアカウント名 vagrant
メインアカウントパスワード vagrant

vagrantユーザの設定

vagrantユーザーでログインをして、Debianの設定をおこないます。 最初にロケールが「ja_JP.UTF-8」ではコンソール上では文字化けをするので「C」に設定しておきます。

$ export LANG=C

続いて、vagrantユーザーがパスワード無しで管理者権限になれるように設定します。 rootを無効にしてインストールしたなら、vagrantユーザーはsudoグループに入っているので、visudoを使い%sudoの行にNOPASSWDを追加します。

$ sudo /usr/sbin/visudo
# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) NOPASSWD:ALL

rootユーザーを有効にしている場合は、sudoをインストールしてvagrantユーザーをsudoグループに追加してから上の設定をおこないます。

$ su -
# apt-get install sudo
# usermod -G sudo vagrant

GuestAdditionsの設定

VirtualBoxにDebianをインストールすると、自動的にvirtualbox-guest-dkmsパッケージがインストールされるので改めてインストールする必要はありませんが、気になる人はこれらのパッケージを削除してインストールしなおしてもよいと思います。 (VirtualBoxとGuestAdditionsのバージョンが異なった状態でVagrantを使うと警告が出ますが、GuestAdditionsの機能はホストゲスト間のファイル共有しか使っていないので、よほど大きくバージョンが異ならなければ問題は出ないはず。)

$ sudo apt-get purge virtualbox-guest-dkms virtualbox-guest-utils
$ sudo apt-get install build-essential dkms
(VirtualBoxのメニューの[デバイス]→[GuestAdditionsのインストール]を選択してから)
$ sudo mount /media/cdrom
$ sudo sh -C /media/cdrom/VBoxLinuxAdditons.run

SSHのインストール

SSHを使うための設定をします。 ca-certificatesパッケージは、wgetでSSH公開鍵を取得する際に必要になるのでインストールしています。

$ sudo apt-get install ssh ca-certificates
$ sudo sh -c "echo 'UseDNS no' >> /etc/ssh/sshd_config"
$ mkdir ~/.ssh/
$ wget -O ~/.ssh/authorized_keys https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub
$ chmod 700 ~/.ssh/
$ chmod 600 ~/.ssh/authorized_keys

その他の設定

あとは適当にrubyやchefなどをインストールしたり、いろいろ必要なことをおこないます。

クリーンアップ

これは定番ですね。不要なDebianパッケージを削除します。

$ sudo apt-get autoremove
$ sudo apt-get clean
dhcpの情報を削除する

気になる人は気になるかもしれないdhcpの情報を削除しておきます。

$ sudo rm /var/lib/dhcp/dhclient.*
$ sudo rm /etc/resolv.conf
grubの待ち時間をなくす

vagrant upしたとき、ちょっと早くなるかな? /etc/default/grubを編集してGRUB_TIMEOUTの値を0にします。

$ sudo vi /etc/default/grub
GRUB_TIMEOUT=0

編集がおわったgrubの設定を更新します。

$ sudo /usr/sbin/update-grub

Vagrantパッケージ化とテスト

ベースとなる仮想マシンが出来ればVagrant用にパッケージ化します。

$ vagrant package --base vagrant-debian-wheezy

パッケージ化出来るとpackage.boxというファイルができているので、package.boxを登録してみます。例ではd7という名前で登録しました。

$ vagrant box add d7 package.box
[vagrant] Downloading with Vagrant::Downloaders::File...
[vagrant] Copying box to temporary location...
[vagrant] Extracting box...
[vagrant] Verifying box...
[vagrant] Cleaning up downloaded box...

適当なディレクトリを作成して登録したboxのテストをします。

$ mkdir test_env
$ cd test_env

$ vagrant init d7
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

登録したboxを起動します。

$ vagrant up
[default] Importing base box 'd7'...
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] The guest additions on this VM do not match the install version of
VirtualBox! This may cause things such as forwarded ports, shared
folders, and more to not work properly. If any of those things fail on
this machine, please update the guest additions and repackage the
box.

Guest Additions Version: 4.1.18
VirtualBox Version: 4.2.12
[default] Mounting shared folders...
[default] -- v-root: /vagrant

無事起動したようです。SSHのポートをポートフォワーディングしてますね。 /vagrantでホストとゲスト間のファイルを共有できます。

SSHでログインしてみます。

$ vagrant ssh
Linux vagrant-debian-wheezy 3.2.0-4-686-pae #1 SMP Debian 3.2.41-2 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon May  6 23:13:52 2013
/usr/bin/xauth:  file /home/vagrant/.Xauthority does not exist

vagrant@vagrant-debian-wheezy:~$ ls -la
total 32
drwxr-xr-x 3 vagrant vagrant 4096 May  6 23:31 .
drwxr-xr-x 3 root    root    4096 May  6 23:13 ..
-rw------- 1 vagrant vagrant   67 May  6 23:31 .Xauthority
-rw------- 1 vagrant vagrant  405 May  6 23:19 .bash_history
-rw-r--r-- 1 vagrant vagrant  220 May  6 23:13 .bash_logout
-rw-r--r-- 1 vagrant vagrant 3392 May  6 23:13 .bashrc
-rw-r--r-- 1 vagrant vagrant  675 May  6 23:13 .profile
drwx------ 2 vagrant vagrant 4096 May  6 23:17 .ssh

ということで作成できました。

あとは巷に溢れるblogなどをみながらいろいろ試すとよいと思います。

_ zerofreeを使うとかなりファイルサイズがかなり縮む

zerofreeというのは、ext2/3/4用のファイルシステムの空き領域をゼロクリアするツールです。 Vagrantのboxを上のような感じで何も考えず作ると、だいたい400〜500MBになりますが、zerofreeで空き領域をクリアするとかなり縮みます。

$ ls -lah
合計 724M
drwxr-xr-x   2 jun jun 4.0K  5月  7 12:20 .
drwxr-xr-x 241 jun jun  20K  5月  7 12:20 ..
-rw-r--r--   1 jun jun 3.9K  5月  7 11:36 Vagrantfile
-rw-r--r--   1 jun jun 277M  5月  7 11:18 package.box
-rw-r--r--   1 jun jun 448M  5月  6 23:22 package.box_old

package.box_oldは何も考えず作ったもので448MBありましたが、zerofreeで空き領域をクリアしたpackage.boxは277MBと171MBも差がでました。

使い方としては、Debianではサクッと apt-get install zerofree でインストールして、root権限で

zerofree -v (パーティション)

とすれば使えますが、アンマウントしたパーティションかリードオンリーでマウントされたパーティションにしか使えないので、自分はライブCDを起動して、そこから実行しました。

これはいいかも。


2013-05-06 [長年日記]

_ ゴールデンウィークももう終わり

ゴールデンウィーク前に「リズムを整えられるかな」とこの日記を書いて公開するのを忘れてました。orz

まあ、彼女の人が遊びに来てたり、田吾作が戻ってきてたり、4月の評価をつけてたり、いろいろあったゴールデンウィークも今日でオシマイです。平常運転平常運転。

Tags: life

_ SULKのCDが間違って送られてきた

上がレンタル用のCD。下が販売用

ゴールデンウィークの話しと言えば、面白いことがあったので書いておこう。

Amazonで注文していたThe SchoolSULKのCDがGW中に届いたので開けてみたけれど何かヘン。 The SchoolとSULKどちらも国内盤を買ったのだけれど、SULKのほうには帯はついているけど対訳・解説が入ってない。 あらためてSULKの国内盤告知ページを見ると、対訳・解説付きと書いてある。

やっぱり、これはおかしい。と思って、販売元のヴァイナルジャンキーさんに問い合わせをしたら、なんと、流通のウルトラヴァイブさんの手違いでTSUTAYA専用レンタルCDがAmazonに間違って流れていたとのこと。 (写真で言うと上がレンタル用、下が販売用。違いはレンタル用は歌詞対訳なし、盤面がピクチャーレーベルでない。)

こういう事もあるんだなー。と思ったゴールデンウィークでした。

追記

そうそう。これは書いておかなければ。ヴァイナルジャンキーさんとウルトラヴァイブさんには、とても丁寧に対応していただきました。 ありがとうございました。

Tags: music amazon

2013-05-05 [長年日記]

_ Debian 7.0 "Wheezy" リリース

お疲れ様でした。

今回Debian Liveは通常のLiveに加えて、nonfreeのファームウェアが入っている非公式版のLiveも用意されています。

公式のほうはミラーされると思うけど、非公式はミラーされないと思うので、ひとまずお知らせ。

Tags: debian

2013-04-26 [長年日記]

_ ゴールデンウィークで立て直したいな

非常勤講師は週2だから大丈夫、かと思ったけど、そもそも大学のシステム自体に慣れてないので、もうgdgdでございました。いや、大した事はまったくやってないのだけど、なんでこんなに疲れてるのかと考えてみると、やっぱり慣れてないからかなと思ったですよ。

で、来週からゴールデンウィークですが、この間、授業は無いのでgdgdになった生活リズムやスケジュールとかを立て直したいなぁ。

Tags: life

_ 「簡単」という名の壁

3週間授業をやってみて思ったのが、学部によって授業の姿勢が全然違うんですよね。

授業がすんなり進む学部と、すんなり進まない学部。

自分の時代から考えると「コンピュータは使えて当たり前」だと思っていた世代の子らが、キーボードを打ったりメールを送るだけの事にとても苦労している。かたや、スイスイ使える子。

と、これだけなら、あるあると思うかもしれないけど、PCからメールを送ることに苦労してても、スマホでパズドラをやってたりする。

いろいろあるなと思いましたよ。

Tags: life
本日のツッコミ(全3件) [ツッコミを入れる]

_ takaya [少し前まではキーボード打てることが多かったのですが, 最近はスマホなどの影響でキーボードの配列が分からない子が増え..]

_ takaya [s/打てることが/打てる子が/]

_ nogajun [ガラケー世代の人で携帯は使えるけどPCは使えない人がいた、という話しは聞いていたけれど、スマホになっても変わらないの..]


2013-04-08 [長年日記]

_ 姫路獨協大学の非常勤講師になりました

姫路IT系勉強会などでお世話になってる姫路獨協大学の園田先生から「Word/Excelを教える先生がいないのだけどやってみる?」とお話しをいただいて、「やります〜」と答えたのが2月終わりぐらい。

そんなこんなで、いろいろやりとりがあって気がつけば4月。打ち合わせが4月5日の金曜日にあって、土日、彼女の人と遊びに行くつもりだったけどキャンセルして準備して今日、新年度一発目の授業でした。

しょっぱなから1限と4限、5限はキツかったぁ。最後はフラフラでした。

自分は通信制の大学に一瞬だけ居たことがあるぐらいで、大学のことなんて何もわからないし、授業の方針や資料は中心になってまとめられてる先生におんぶに抱っこのマイナス状態ですが、とりあえず1年続けられるようがんばります。

Tags: life

_ Debian JP Projectの副会長になりました

つづいて

ということで、Debian JP Projectの副会長をお受けしました。

最近、姫路IT系勉強会など姫路の活動のほうが多くて、Debian関係のアクティビティはかなり落ちていますが、こっちも力を入れて頑張れとのことなので、こちらも頑張りたいと思います。

Debian Liveやfontconfigのデフォルトの話、ほかWordPressパッケージでプラグインを使うとパスの違いでコケるところものが多い問題とか気になっているけど手をつけてない/英語で億劫になってる事もありますが徐々に手をつけていきます…。

Tags: debian

2013-03-31 [長年日記]

_ 花見と散歩

nogajun's photo.

彼女の人と花見がてらの散歩。

nogajun's photo.

そして、散歩先であった謎のモニュメント。あれはなんだ?

Tags: life

2013-03-29 [長年日記]

_ シェルスクリプト(bash)のメッセージを国際化する 2013年版

シェルスクリプトのメッセージを国際化するといえば「bash スクリプト内メッセージの国際(カタログ)化」に書かれている方法が有名ですが、この方法はセキュリティ上の問題(シフトJISや中国語のエンコーディングではダブルクォーテーションを無効にできてしまうなど。くわしくは「bash - GNU `gettext' utilities」を参照)から現在、非推奨になっています。

現在推奨されているメッセージの国際化は、手順自体が大幅に変わったワケではありませんが、全体を通してまとまった文書は日本語ではないようなので、まとめておきます。

参考

以前との違い

大きな違いとしては、国際化したいメッセージの部分を「$"Msgid"」と書いていたものが、「"$(eval_gettext "Msgid")"」という書き方になりました。それにともない、事前にラッパーのgettext.shを読み込ませる必要があります。

シェルスクリプトのメッセージを国際化する

ここからは、シェルスクリプトのメッセージを実際に国際化対応していきます。

サンプルと実行例

サンプルとしてHello Worldと表示するシェルスクリプトを使いました。

#!/usr/bin/env bash
# hello.sh -- say hello script
echo hello world

実行例

$ ./hello.sh
hello world

メッセージのカタログ化事前準備

メッセージをカタログ化を準備するため、ラッパーのgettext.shを読み込ませます。 読み込ませる方法は「. gettext.sh」(一番前にドットがあります。)という行を追加します。 追加する行は、先頭の部分、シェバンの下あたりに書くとよいでしょう。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh
echo hello world

メッセージをカタログ化

国際化したいメッセージをカタログ化します。 まず、メッセージの部分をダブルクォーテーションで囲み、その前に「eval_gettext」と書きます。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh
echo eval_gettext "hello world"

eval_gettextはgettext.shに含まれる関数ですが、このままでは文字列としか扱われてないので、バッククォート「`」もしくは「$(」と「)」でeval_gettextと文字列をくくり、関数として実行されるようにします。そして「$(」と「)」の外をダブルクォーテーションでくくります。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh
echo "$(eval_gettext "hello world")"

potファイルの生成

xgettextを使って(bash --dump-po-stringsは使わない)メッセージカタログの元になる、potファイルを生成します。「-o」オプションで出力ファイル名をつけて、xgettextを実行します。

$ xgettext -o hello.pot hello.sh
$ cat hello.pot

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 22:25+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: hello.sh:4
#, sh-format
msgid "hello world"
msgstr ""

メッセージカタログを作成

potファイルをコピーし、言語のpoファイル(メッセージカタログ)を作成します。

$ cp hello.pot ja.po

適当なエディタを使い、ja.poをそれぞれの言語に翻訳します。 poeditなどの専用エディタならpoファイルの情報はそれぞれ適切に設定されますが、テキストエディタのみで作業する場合は、最低「Content-Type:」のCHARSETはUTF-8に設定してください。

$ cat ja.po

# hello ja.po
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 22:26+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: Japanese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" ← CHARSETをUTF-8にしておく
"Content-Transfer-Encoding: 8bit\n"

#: hello.sh:4
#, sh-format
msgid "hello world"
msgstr "こんにちは 世界" ←msgidに対応した文を翻訳する

poファイル(メッセージカタログ)のコンパイルと配置

poファイルをコンパイルしmoファイルを生成。メッセージカタログのディレクトリに配置します。

まずカレントディレクトリにmoファイルを置くディレクトリを作成します。

$ mkdir -p ja/LC_MESSAGES

poファイルをコンパイルします。moファイルの出力先は「-o」オプションで変更できるので、ja/LC_MESSAGES/(アプリケーション名).mo とします。

$ msgfmt -o ja/LC_MESSAGES/hello.mo ja.po

メッセージカタログの適用テスト

メッセージカタログが生成できたので、スクリプトにそれぞれの言語でメッセージカタログが適用されるかテストします。

通常、メッセージカタログは /usr/share/locale/ja/LC_MESSAGES (日本語の場合)以下に置かれますが、メッセージディレクトリを指す環境変数 TEXTDOMAINDIR と、アプリケーション名を指す環境変数 TEXTDOMAIN を変更するとカレントディレクトリを指定できるので、それぞれを変更してテストをおこないます。

LANGにCを設定した場合
$ LANG=C TEXTDOMAIN=hello TEXTDOMAINDIR=. ./hello.sh
hello world

LANGにja_JP.UTF-8(日本語)を指定した場合
$ LANG=ja_JP.UTF-8 TEXTDOMAIN=hello TEXTDOMAINDIR=. ./hello.sh
こんにちは 世界

それぞれ適用できました。

TEXTDOMAINDIRの設定とメッセージカタログのアップデート

スクリプトを実行する際、いちいち「TEXTDOMAIN=hello TEXTDOMAINDIR=.」をつけての実行は面倒なので、スクリプトの中に書いてしまいます。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh

TEXTDOMAIN=hello
export TEXTDOMAIN
TEXTDOMAINDIR=/home/hoge/src/hello/
export TEXTDOMAINDIR

echo "$(eval_gettext "hello world")"

TEXTDOMAINは変わりませんが、TEXTDOMAINDIRは、「.」のままではカレントディレクトリを示して、別のディレクトリからスクリプトを実行するとメッセージカタログが適用されないので、フルパスでスクリプトのディレクトリを指定します。

スクリプトが変更されたので、メッセージの位置が変わります。ですのでメッセージカタログもアップデートします。

xgettextでpotファイルの生成は同じですが、msgmergeを使ってja.poをアップデートします。

$ xgettext -o hello.pot hello.sh
$ msgmerge -U ja.po hello.pot

上のような些細な変更ではなくメッセージの追加などあれば、未翻訳の部分もあるのでpoファイルに未翻訳部分の翻訳も追加します。 追加が終わればpoをコンパイルします。

$ msgfmt -o ja/LC_MESSAGES/hello.mo ja.po

正しくメッセージカタログが適用されるかテストします。

英語
$ LANG=C ./hello.sh
hello world

日本語
$ LANG=ja_JP.UTF-8 ./hello.sh
こんにちは 世界

ディレクトリを変更してもメッセージカタログが適用されるかテストします。

$ cd ~/
$ LANG=C src/hello/hello.sh
hello world
$ LANG=ja_JP.UTF-8 src/hello/hello.sh
こんにちは 世界

これで問題なくメッセージカタログが適用されるようになりました。

文字列を非推奨の「$"..."」で囲んでいるスクリプトにxgettextを使うと

文字列をこれまで解説をした「"$(eval_gettext "...")"」ではなく、非推奨の「$"..."」で囲んでいるスクリプトに、xgettextでメッセージカタログを生成しようとすると警告されます。

$ cat hello-old.sh
#!/usr/bin/env bash
# hello.sh -- say hello script
echo $"hello world"
$ xgettext -o hello-old.pot hello-old.sh
hello-old.sh:3: 警告: 文法 $"..." はセキュリティ上の理由で推奨されません. 代わりに eval_gettext を使ってください

bash --dump-po-stringsでは何も出ません。

$ bash --dump-po-strings hello-old.sh > hello-old.pot

ということで、メッセージカタログの作成にはxgettextを使いましょう。

_ シェルスクリプトだけで空白で区切られた文字列から特定部分だけ抜き出し、入れ替えて表示

シェルスクリプトを使っていて空白で区切られた文字列「"AAA BBB CCC DDD EEE"」から2番目のBBBと5番目のEEEを取り出し、入れ替えて「EEE BBB」と表示したい場合、cutやawkを使うのもよいですが、いったん配列に入れると位置を指定して取り出すことができます。

1: T="AAA BBB CCC DDD EEE"
2: F=(${T})
3: echo "${F[4]} ${F[1]}"

EEE BBB

1行目: 空白で区切られた文字列「"AAA BBB CCC DDD EEE"」が変数Tに入ってます。

2行目: 配列に代入するとき、F=(A B C D E)のようにするとF[0]=A, F[1]=Bのように配列Fにそれぞれ分割されて代入されます。ここに空白で区切られた文字列$Tを指定すると、F[0]=AAA, F[1]=BBBのように分割されて配列Fに代入されます。

3行目: ということで、F[4]に文字列「EEE」、F[1]に文字列「BBB」が入っているので、それぞれ指定してechoで表示しています。


2001|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|06|08|12|
2011|01|02|03|06|07|08|09|10|11|12|
2012|01|02|03|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|