0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

dashで位置パラメタを退避しようとしたら入れ子の配列が使えるようになった

Posted at

配列代わりに何かと便利な位置パラメタを退避できると嬉しいときがあるような気がした。
(esc関数の定義はここを参照)

arr() {
  local RET args= arg

  for arg in "$@"; do
    esc "$arg"
    printf ' %s' "$RET"
  done
}
alias backup_args='arr "$@"'
alias restore_args='eval "set --"'
$ set -- 'a b' "c'"
$ hoge="`backup_args`"
$ echo $hoge
'a b' 'c'\'''
$ set --
$ echo "$1"

$ restore_args "$hoge"
$ echo "$1"
a b
$ echo "$2"
c'

evalで解釈するとシングルクォート囲みの文字列が各フィールドにsetされるように
文字列を作成するだけなのだが、これを使うと任意の文字列の配列が入れ子で
作成できることに気がついた。

$ m=$(arr "`arr 1 2 3`" \
          "`arr 4 5 6`" \
          "`arr 7 8 9`")
$ echo $m
' '\''1'\'' '\''2'\'' '\''3'\''' ' '\''4'\'' '\''5'\'' '\''6'\''' ' '\''7'\'' '\''8'\'' '\''9'\'''
$ restore_args "$m"
$ echo $2
'4' '5' '6'
$ restore_args "$2"
$ echo $1
4
$ echo $2
5

位置パラメタを汚さずにアクセスできるようにiter関数を定義してみる。

iter() {
  local head=$1 tail=$2
  eval "restore_args \"\$$2\""
  [ $# -gt 0 ] || return
  eval "$head='$1'"
  shift
  eval "$tail="'"`backup_args`"'
}
$ a="`arr 1 2 3 4`"
$ while iter i a; do echo $i; done
1
2
3
4

※性能を気にする人はコマンド置換を避けて定義し直すとよいかも。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?