Como manipular opções ao abrir um arquivo passado como argumento? [fechadas]

0

Estou tentando abrir um arquivo por meio de um script; contanto que eu passe o arquivo como o primeiro argumento, não há problemas; por exemplo:

$ 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

em que tester.sh é escrito assim:

#!/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

Apenas o sinalizador -h funciona porque existe uma declaração de saída:

$ ./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.

Portanto, modifiquei o script, introduzindo uma etapa para verificar se o argumento é um sinalizador:

#!/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

e o resultado é:

$ ./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

O problema é: se eu adicionar outro argumento para salvar a linha em um arquivo de um nome de escolha, tenho outro problema. Modificando o arquivo em:

#!/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

a saída é:

$ ./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

Ou seja: não há mais arquivo de entrada, o bash está olhando para o argumento my_file como o arquivo de entrada.

Estive pensando em colocar o arquivo de saída entre aspas simples ou duplas e verificar sua presença, mas não consigo escapar da citação, portanto, recebo um erro. Modificando a seção:

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

Eu recebo:

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

Ou seja, o bash não reconhece as aspas no argumento. Eu tentei diferentes opções, como "\ '",' \ '' etc, bem como $ i, "$ i".

Existe uma maneira de verificar a presença de cotações em uma discussão? Ou uma maneira melhor de lidar com argumentos?

    
por Gigiux 31.08.2018 / 16:34

1 resposta

1

Depois de processar as opções com getopts , a variável OPTIND é definida para o índice do primeiro argumento não-opcional, então faça isso:

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

Agora, $1 contém o nome do arquivo.

    
por 31.08.2018 / 21:19