如何用bash提取命令行参数中多个不同参数各自的数组值, 并保存为数组?

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
careone
帖子: 805
注册时间: 2007-12-17 21:41
送出感谢: 71 次
接收感谢: 24 次

如何用bash提取命令行参数中多个不同参数各自的数组值, 并保存为数组?

#1

帖子 careone » 2013-04-22 22:36

待解决问题: 如何用bash提取命令行参数中多个不同参数各自的数组值, 并保存为数组?

说明: 下面的代码能实现, 但是因为用到多层管道, 代码比较复杂. 请教是否有更为简便可行的方案?

代码: 全选

#! /bin/bash
# coding: utf8
DEBUG=1

### ----------------- ###
# 待解决问题: 如何用bash提取命令行参数中多个不同参数各自的数组值, 并保存为数组?
# 示例如下:


#cmd: emacs-locale -v 23.1 24.3 24.1 23.1 -l zh_CN zh_TW
# 參數輸入順序也可能是這樣的:
#cmd: emacs-locale -l zh_CN zh_TW -v 23.1 24.3 24.1 23.1
#
#目的: 通過調用相應的翻譯腳本, 把 Emacs 的英文版 .el 文件, 分別翻譯為 
#  23.1, 24.1, 24.3 的簡體中文版本 (zh_CN), 再翻譯為23.1/24.1/24.3
#  的繁體中文版本(zh_TW), 實現 Emacs 菜單本地化.
# 注1: 輸入的 -v 及後續參數中, 需要進行排序, 并去除重復的版本號
# 注2: emacs-locale -v 參數及後續參數中, 需要提取第1個小數點前面的數字,
#     保存為變量值: $MVER (即 Major_Version, 主版本號), 以及数组 $ARRAY_MVER
#     因為有時命令行輸入的版本號也可能是這樣: emacs-locale -v 24.3.99 -l zh_CN
#     如果版本數字後沒有帶小數字點, 那麽 版本號=$MVER (主版本號)
# 注3: 擴展和保留功能: 如果命令行輸入是 xemacs-locale -v 21.4.29 -l zh_CN
#     提取主版本號參數時, 需要把第2個小數點前的數字保存為變量"主版本號" $MVER,
#     即 XEmacs 21.4.29 的主版本號應是 21.4, 而不是類似 Emacs 的 21  

# 當前解決思路:
# 先把所有參數保存為 ~/.emacs.d/emacs-locale/cmdline,
# 再用 sed 把 -l 和 -v 通過替換, 處理成各自單獨的行,
# 再用 echo 功能配合 sort 和管道, 對各自的數組值排序并去除重復項,
# 再用 grep 分別顯示包含 -l 和 -v 行, 并保存為數組 $ARRAY_ELANG, $ARRAY_EVER
# 最後再運行 emacs-locale -l ${ARRAY_ELANG[@]} -v ${ARRAY_EVER[@]}

## 当前数组的获得方式太复杂, 不知有没有更简单的方法? 请bash高手指点!
### ----------------- ###


### code begin ###
declare -a ARRAY_ELANG
declare -a ARRAY_EVER
declare -a ARRAY_MVER

if [ ! -d "$HOME/.emacs.d/emacs-locale/" ]; then
  mkdir -p "$HOME/.emacs.d/emacs-locale/"
fi

# 保存參數字符串到文件 cmdline

### 以下是用于调试的模拟数据, 调试成功后会禁用或删除 ###
#CMDLINE='emacs-locale -l zh_CN zh_TW -v 23.1 24.3 24.1 23.1'
CMDLINE='-l zh_CN zh_TW -v 23.1.25 24.3 24.1 23.1 24 25.1.2.3'
echo -e "L51 cmd:\n$0 $CMDLINE"
echo "$CMDLINE" > ~/.emacs.d/emacs-locale/cmdline

## 保存全部参数 $* 到指定文件 cmdline
#echo "$*" > ~/.emacs.d/emacs-locale/cmdline

### 调试数据结束 ###

# 如果 cmdline 文件內容同時包含 -l 和 -v 字符串, 處理成單獨的兩行,再執行數組提取
if grep "\-l" "$HOME/.emacs.d/emacs-locale/cmdline" &>/dev/null && grep "\-v" "$HOME/.emacs.d/emacs-locale/cmdline" &>/dev/null ; then
  sed -i 's/-l/\n-l/' $HOME/.emacs.d/emacs-locale/cmdline
  sed -i 's/-v/\n-v/' $HOME/.emacs.d/emacs-locale/cmdline
fi

# array 1: multi Emacs languages
ARRAY_ELANG=( `grep "^\-l" "$HOME/.emacs.d/emacs-locale/cmdline" | sed 's/^-l//;s/\ /\n\ /g' | sort | uniq` )

# array 2: multi Emacs versions
ARRAY_EVER=( `grep "^\-v" "$HOME/.emacs.d/emacs-locale/cmdline" | sed 's/^-v//;s/\ /\n\ /g' | sort | uniq` )

# optional array 3 for Emacs: multi Emacs major versions
## for example: Emacs 24.2/24.2.99, major_version = 24
ARRAY_MVER=( `grep "^\-v" "$HOME/.emacs.d/emacs-locale/cmdline" | sed 's/^-v//;s/\ /\n\ /g' | sort | uniq | sed 's/[\.]/\ /' | cut -d' ' -f2 | uniq` )

## optional array 3 for XEmacs: multi XEmacs major versions
## for example: XEmacs 21.4.29, major_version = 21.4
#ARRAY_MVER=( `grep "^\-v" "$HOME/.emacs.d/emacs-locale/cmdline" | sed 's/^-v//;s/\ /\n\ /g' | sort | uniq | sed 's/[\.]/\ /2' | cut -d' ' -f2 | uniq` )

if [ "$DEBUG" = 1 ]; then
echo -e "L80 result:"
echo "---------------"
echo "${ARRAY_ELANG[*]}"
echo "${ARRAY_EVER[*]}"
echo "${ARRAY_MVER[*]}"
echo "---------"
echo "${ARRAY_ELANG[@]}"
echo "${ARRAY_EVER[@]}"
echo "${ARRAY_MVER[@]}"
fi
exit 0;
输出如下:

代码: 全选

user@ubuntu:~/bin$ ./emacs-locale.sh
L51 cmd:
./emacs-locale.sh -l zh_CN zh_TW -v 23.1.25 24.3 24.1 23.1 24 25.1.2.3
L80 result:
---------------
zh_CN zh_TW
23.1 23.1.25 24 24.1 24.3 25.1.2.3
23 24 25
---------
zh_CN zh_TW
23.1 23.1.25 24 24.1 24.3 25.1.2.3
23 24 25
魁拔不死,天下不宁。
魁拔既死,天下不平。
--------------
Careone <emacslocale^126.com>
https://sourceforge.net/projects/emacslocale/files/
头像
枫叶饭团
论坛版主
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
送出感谢: 1 次
接收感谢: 132 次
联系:

Re: 如何用bash提取命令行参数中多个不同参数各自的数组值, 并保存为数组?

#2

帖子 枫叶饭团 » 2013-04-22 22:43

我现在看见shell就想砍人!
回复

回到 “Shell脚本”