1

我从这个名为 wd 的脚本开始:

cat "$@" | tr -cs '[:alpha:]' '\n' | tr '[:upper:]' '[:lower:]' 
| sort | uniq -c | sort -n | awk '{print $2 " " $1}' | sort

这将任意数量的文件作为输入并打印文件中单词的分布,如下所示:

wd file1 file2

blue 2
cat 3
the 5
yes 1

现在我正在尝试为其添加 2 个选项:s 和 t。s 使脚本获取一个名为 stopwords 的输入文件,并在进行分发之前从输入文件中删除这些词。t 将数字 n 作为参数,仅输出前 n 个单词。默认为所有单词。

所以,到目前为止,我有这个脚本。目前,我的问题是当我尝试使用 -t 10 选项时,它告诉我找不到文件 10,但无论如何它应该是一个数字,而不是文件。而且,当我尝试使用 -s 选项时,它什么也不做,但不输出任何错误。我知道这个问题不是很具体,但我会很感激任何关于错误的想法。

#!/bin/bash

stopwords=FALSE
stopfile=""
topwords=0

while getopts s:t: option 
do
    case "$option"
    in
        s) stopwords=TRUE
        stopfile="$OPTARG";;
        t) topwords=$OPTARG;;
        \?) echo "Usage: wd [-s stopfile] [-t n] inputfile"
            echo "-s takes words in stopfile and removes them from inputfile"
            echo "-t means to output only top n words"
            exit 1;;
    esac
done

if [ "stopwords" = FALSE ]
then
    cat "$@" | tr -cs '[:alpha:]' '\n' | tr '[:upper:]' '[:lower:]' 
| sort | uniq -c | sort -nr | head -n $topwords | awk '{print $2 " " $1}' | sort
else
    cat "$@" | grep -v -f "$stopfile" |  tr -cs '[:alpha:]' '\n' | tr '[:upper:]' '[:lower:]' 
| uniq -c | sort -nr | head -n $topwords | awk '{print $2 " " $1}' | sort
fi
4

1 回答 1

2

通常在while getopts循环之后你需要shift $((OPTIND - 1)). ksh以下是我之前为and编写的示例bash

PROGNAME=$0

function _echo
{
    printf '%s\n' "$*"
}

function usage
{
    cat << END
usage: $PROGNAME [-a] [-b arg] [-h] file...
END

    exit $1
}

function parseargs
{
    typeset opt v

    [[ $# = 0 ]] && usage 1

    while getopts ":ab:h" opt "$@"; do
        case $opt in
            a)   _echo -$opt ;;
            b)   _echo -$opt $OPTARG ;;
            h)   usage ;;
            :)   _echo "! option -$OPTARG wants an argument" ;;
            '?') _echo "! unkown option -$OPTARG" ;;
        esac
    done
    shift $((OPTIND - 1))

    for v in "$@"; do
        _echo "$v"
    done
}

parseargs "$@"
于 2013-03-19T01:53:12.343 回答