当前面有 bash 参数时,Getopts 不起作用

Getopts doesn't work when there is a bash parameter before

我在使用 getopts 和简单的 bash 参数时遇到问题。我的脚本从匹配指定表达式的文件行中写出。

-f 选项允许你改变文件

-n选项改变写出的行数

第一个参数$1决定表达式的类型

示例文件 (file.txt):

aaaaaaaaaaaa
bbbbbbbbbbba
cccccccccccc
ab
ac
dddddddddddd
dgdgdgdgdgdg
abdbdbdbdbdb

订单示例:

./script.sh a -f file.txt -n 2

示例输出:

aaaaaaaaaaaa
ab

我的脚本:

while getopts ":n:f:" opt
        do
        case $opt in
        (n)  
                argn=$OPTARG
                ;;
        (f)
                argf=$OPTARG
                ;;
        esac
        done

FOO=${argf:=/etc/passwd}
NR=${argn:=3}


echo " --------- ^ -----------"
awk -F':' '/^'""'/ { print  }' $FOO | head -n $NR

它仅在我输入

时有效
 ./script.sh a 

./script.sh b 

(给我以这封信开头的行)。或者当我刚刚输入

 ./script.sh -n 5 

./script -f file.txt

当我想同时使用参数 ($1) 和选项时,它不起作用。我能做什么?

感谢您的回答!

这就是 getopts 的工作原理。它在第一个非选项参数处停止。

如果你想做你想做的事情(顺便说一下,我不会推荐它)那么你可以先手动删除你的选项(然后正常调用 getopts)或者通过手动 getopts 的其余参数。

所以要么

opt1=
shift

while getopts ":n:f:" opt
....
done

echo " --------- ^opt1 -----------"

while getopts ":n:f:" opt "${@:2}"
....
done

echo " --------- ^ -----------"

我同意伊坦的观点。这是您应该做的事情:

# I like to declare my vars up front
# your use of FOO=${argf:=/etc/passwd} is of course OK

file=/etc/passwd
max_matches=3

while getopts ":n:f:" opt; do
    case $opt in
        n) max_matches=$OPTARG ;;
        f) file=$OPTARG ;;
        :) echo "missing argument for option -$OPTARG"; exit 1 ;;
       \?) echo "unknown option -$OPTARG"; exit 1 ;;
    esac
done
shift $((OPTIND-1))    # remove the processed options 
pattern=             # NOW, get the search term.

grep -m "$max_matches" "^$pattern" "$file"

然后你将执行它:

./script.sh -f file.txt -n 2 a
./script.sh -f file.txt a
./script.sh -n 2 a
./script.sh a

注意,don't use ALL_CAPS_VARS