【问题标题】:Parse command line args to process a list of files in bash?解析命令行参数以处理 bash 中的文件列表?
【发布时间】:2015-08-12 15:24:46
【问题描述】:

我想创建一个脚本,其中包含一些可选输入,其解析方式类似于this respone 的解释,但还包含具有特定扩展名的文件列表。示例用法是

./myscript.sh -s 25 -q 0.2 *.txt

然后脚本会将 25 存储到 s 变量中,将 0.2 存储到 q 变量中,然后将单独处理所有 txt 文件的列表。这就是我目前所拥有的

#!/bin/bash -f

# set the default values
QMAX=0.2
PROFILESIZE=50

while [[ $# > 0 ]]
do
key="$1"
case $key in
    -q|--max_q)
    QMAX="$2"
    shift # past argument
    ;;
    -s|--profile_size)
    PROFILESIZE="$2"
    shift # past argument
    ;;
esac
shift # past argument or value
done

for var in "$@"
do
    if [[ $var == *".txt" ]]
    then
        # do something on for real on each file here
        echo $QMAX $PROFILESIZE $var
    fi
done

按原样,我可以通过注释掉while 循环来使用默认值运行。没有注释掉它,它会读取输入,并且没有任何内容可供for 循环进行比较。我认为最好的选择是在while 循环中创建文件列表,然后在for 循环中使用它。关于我将如何做到这一点的任何想法?

【问题讨论】:

    标签: string bash list parsing


    【解决方案1】:

    只需附加一个 *) 将参数存储到数组的 case。

    *) files+=("$1") ;;
    

    然后遍历文件而不是$@

    for file in "${files[@]}" ; do
    

    【讨论】:

    • 这正是我想要做的。效果很好。
    【解决方案2】:

    第一个建议是不要从头开始实现它,而是使用“getopts/getopt”。但是,如果由于某种原因可以,并且假设选项总是在参数之前:

    #!/bin/bash 
    
    # set the default values
    QMAX=0.2
    PROFILESIZE=50
    
    while [[ $# > 0 ]]
    do
     key="$1"
     case $key in
     -q|--max_q)
       QMAX="$2"
       shift 2 # past argument
      ;;
      -s|--profile_size)
        PROFILESIZE="$2"
        shift 2 # past argument
       ;;
      *)
       break
       ;;
    
    # --) 
    # break
    # ;;
    
      esac
    done
    
    for var in "$@"
    do
      if [[ $var == *".txt" ]]
      then
        # do something on for real on each file here
        echo $QMAX $PROFILESIZE $var
      fi
    done
    

    【讨论】:

    • 我必须在参数之前始终拥有选项吗?如果没有break 语句,输入不能按任何顺序排列吗?
    • 如果参数和选项混合在一起,那么您需要一个由@choroba 建议的辅助数组。但是,这不是很平常,甚至不好让它们混在一起。事实上,通常允许一个可选的“---”,意思是“选项结束,参数开始”。这样,参数可以与选项同名。
    【解决方案3】:

    您可以使用getopts 命令处理可选参数,将剩余参数留在$@

    while getopts 's:q:' opt; do
        case $opt in
            s) PROFILESIZE=$OPTARG ;;
            q) QMAX=$OPTARG ;;
        esac
    done
    shift $(( OPTIND - 1 ))
    

    不过,这确实有不支持长选项的缺点。

    【讨论】:

      猜你喜欢
      • 2014-01-13
      • 2010-09-16
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      相关资源
      最近更新 更多