Bash
Linux
Split
IFS

bashでIFSを使わずにsplitする方法

はじめに

こんな方法があるなんて知らなかった。
IFSなんていらなかったんだ!

ここに載っていたのを模倣しただけです。
でも日本語の記事が見当たらなかったので書きました。

環境

  • OS: macOS Sierra 10.12.4
  • bash: GNU bash, version 3.2.57

やりたいこと

文字列を指定したデリミタで分割して配列に格納したい。
いわゆるsplitです。

まずは結論から

例えばパスからディレクトリの配列を得るにはこうなる。
split(というか置換してるだけ)の処理は一行。便利!

split-sub.sh
#!/bin/bash

path=$1;
declare -a a_dirs=();
a_dirs=${path//\// };

for dir in ${a_dirs[@]};
do
  echo $dir;
done

exit 0;

実行結果

$ ./split-sub.sh $(pwd)
Users
tommarute
script
split_test

今までの方法

よくあるIFSを使ったやり方。

split-ifs.sh
#!/bin/bash

function split() {
    local -a _dirs=();
    path=$1;
    c_ifs=$IFS;
    IFS=$2;
    _dirs=$(echo $path);
    IFS=$c_ifs;
    echo $_dirs;
}

main() {
    declare -a a_dirs=();
    a_dirs=($(split $1 '/'));

    for dir in ${a_dirs[@]};
    do
      echo $dir;
    done
    exit 0;
}

main $@;

実行結果

$ ./split-ifs.sh $(pwd)
Users
tommarute
script
split_test

おまけ

今回書いた方法は、デリミタを空白に置換して配列に変換しているわけで、であればtrでもできるんじゃ。。

と思ってやってみたらできました。
気づかなかった。

#!/bin/bash

path=$1;
declare -a a_dirs=();
a_dirs=$(echo $path | tr '/' ' ');

for dir in ${a_dirs[@]};
do
  echo $dir;
done

exit 0;

実行結果

$ ./split-tr.sh $(pwd)
Users
tommarute
script
split_test

おわりに

bashでIFSを使わずにsplitする方法について書きました。
今までIFS使って書いたコード全てリファクタリングしたい。

!!!ご注意!!!
この記事はあくまで私がIFSを使ったsplitより簡単だと感じた手法について書いたものであり、決してIFSを否定するものではありません。