打开作为参数传递的文件时如何处理选项?

打开作为参数传递的文件时如何处理选项?

我正在尝试通过脚本打开文件;只要我将文件作为第一个参数传递,就没有问题;例如:

$ cat textExample.txt 
Much I marvelled this ungainly fowl to hear discourse so plainly,
Though its answer little meaning- little relevancy bore;
For we cannot help agreeing that no living human being
Ever yet was blessed with seeing bird above his chamber door-
Bird or beast upon the sculptured bust above his chamber door,
With such name as "Nevermore."
$ ./tester.sh textExample.txt 
BEGIN PROGRAM
parse file
For we cannot help agreeing that no living human being

其中tester.sh是这样写的:

#!/bin/bash

# options
optstring=fh
Feature=0
Help=0
while getopts $optstring opt
do
  case $opt in
    f) Feature=1;;
    h) Help=1 ;;
    *) echo WRONG && exit 1 ;;
  esac
done

if [[ $Feature == 1 ]] ; then
    echo "This is a feature of the program"
elif [[ $Help == 1 ]] ; then
    echo "This is the help page"
fi

echo "BEGIN PROGRAM"
# assign file name
file=$1
echo "parse file"
grep 'cannot help' $file

exit 0

只有 -h 标志有效,因为有退出语句:

$ ./tester.sh -h
This is the help page
$ ./tester.sh -f
This is a feature of the program
BEGIN PROGRAM
parse file
grep: option requires an argument -- 'f'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

因此,我修改了脚本,引入了一个步骤来检查参数是否是一个标志:

#!/bin/bash

# options
optstring=fh
Feature=0
Help=0
while getopts $optstring opt
do
  case $opt in
    f) Feature=1;;
    h) Help=1 ;;
    n) Custom_name=$OPTARG ;;
    *) echo WRONG && exit 1 ;;
  esac
done

if [[ $Feature == 1 ]] ; then
    echo "This is a feature of the program"
elif [[ $Help == 1 ]] ; then
    echo "This is the help page"
    exit
fi

for i in $@ ; do
    if [[ "${i}" =~ "-" ]] ; then
        true
    else
        input=$i
    fi
done


echo "BEGIN PROGRAM"
# assign file name
echo "parse file"
grep 'cannot help' $input

exit 0

结果是:

$ ./tester.sh -f
This is a feature of the program
BEGIN PROGRAM
parse file
$ ./tester.sh -f textExample.txt 
This is a feature of the program
BEGIN PROGRAM
parse file
For we cannot help agreeing that no living human being

问题是:如果我添加另一个参数来将该行保存到所选名称的文件中,则会遇到另一个问题。修改文件中:

#!/bin/bash

# options
optstring=fhn:
Feature=0
Help=0
output=
while getopts $optstring opt
do
  case $opt in
    f) Feature=1;;
    h) Help=1 ;;
    n) output=$OPTARG ;;
    *) echo WRONG && exit 1 ;;
  esac
done

if [[ $Feature == 1 ]] ; then
    echo "This is a feature of the program"
elif [[ $Help == 1 ]] ; then
    echo "This is the help page"
    exit
fi

for i in $@ ; do
    if [[ "${i}" =~ "-" ]] ; then
        true
    else
        input=$i
    fi
done


echo "BEGIN PROGRAM"
# assign file name
echo "parse file"
if [[ -z $output ]] ; then
    grep 'cannot help' $input
else
    grep 'cannot help' $input > $output
fi

exit 0

输出是:

$ ./tester.sh -f textExample.txt 
This is a feature of the program
BEGIN PROGRAM
parse file
For we cannot help agreeing that no living human being
$ ./tester.sh -f -n my_file textExample.txt 
This is a feature of the program
BEGIN PROGRAM
parse file
$ ./tester.sh -n my_file textExample.txt 
BEGIN PROGRAM
parse file

也就是说:不再有输入文件,bash 将参数 my_file 作为输入文件。

我一直在考虑将输出文件用单引号或双引号括起来并检查它们是否存在,但我无法转义引号,因此出现错误。修改部分:

for i in $@ ; do
    if [[ "${i}" =~ "-" ]] ; then
        true
    elif [[ "${i}" =~ \' ]] ; then
        true
    else
        input=$i
    fi
done

我得到:

$ ./tester.sh -n 'my_file' textExample.txt 
BEGIN PROGRAM
parse file

也就是说,bash 无法识别参数中的引号。我尝试了不同的选项,例如“\'”、“\”等以及$i、“$i”。

有没有办法检查参数中是否存在引号?或者有更好的方式来处理争论?

答案1

使用 处理选项后getopts,变量OPTIND设置为指数第一个非选项参数,所以这样做:

while getopts $optstring opt; do
    #... 
done
# now, remove the options from the positional parameters
shift $((OPTIND-1))

现在,$1包含文件名。

相关内容