我正在尝试通过脚本打开文件;只要我将文件作为第一个参数传递,就没有问题;例如:
$ 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
包含文件名。