Como grep argumento de linha de comando em que RegEx foi aplicado?

1

Estou tentando escrever um script que tome como entrada um conjunto de inteiros representando determinados /dev/sda . Por exemplo, se os argumentos da linha de comando forem 3 & 5, a saída mostrará o UUID para /dev/sda3 e /dev/sda5 . Meu código é:

#!/bin/bash

### Shows UUID of input /dev's - REQUIRES SUDO

## Options:
## [-m] Multiple Devs   - returns both dev name and UUID
## [  ] No option       - returns only the UUID of the dev.

while getopts m: option
do
    case "${option}"
    in
    m)  echo -e "\nDEV\tUUID\n====\t================"
        blkid | grep .*sda[\"$@\"] | sed -r 's/\/dev\/([[:alnum:]]+).* UUID="([[:alnum:]]+)".*/\t/g'
        ;;
    esac
done

Meu problema principal é com a linha grep .*sda[\"$@\"] , que retorna o seguinte erro:

$ sudo ./dUShow.sh -m 3 5

DEV     UUID
====    ================
grep: Unmatched [ or [^

Agora, se não me engano, isso significa que o problema ocorre quando eu estou tentando fornecer como opções alternativas *.sda[$@] , que eu quero que o RegEx substitua com *.sda[$1$2] , equivalente a *.sda[35] para a entrada fornecida.

Como faço isso?

Entrada de amostra

sudo ./dUShow.sh -m 3 5

Saída desejada

DEV     UUID
====    ================
sda3    BC4208CF42089076
sda5    968E185A8E183569

Adendo

A expressão .*sda[\"$@\"] produzirá *.sda[35] ou *.sda[3 5] ? Se for o último, isso causará um problema? Se sim, como resolvo isso?

    
por Somenath Sinha 29.09.2017 / 14:26

2 respostas

2

Se $ 1 == 3 e $ 2 == 5 então

grep .*sda[\"$@\"]

se transforma em

grep .*sda[3 5]

Qual é um problema devido à falta de cotações. Tente isso:

regex=".*sda($( IFS='|'; echo "$*" ))\>"     # => .*sda(3|5)\>
blkid | grep -E "$regex" | ...

O \> é um limite de palavra, para tornar a regex mais precisa.

Alguma documentação sobre os sabores de expressões regulares do GNU grep:

  1. expressões regulares básicas
  2. expressões regulares estendidas
por 29.09.2017 / 14:57
1

Para correspondências de um único dígito, você pode colocar a string de argumento diretamente nos colchetes RE. (Eu acho que isso é o que você estava originalmente tentando fazer.)

grep "/dev/sda[$*]:"

Observe que $* incluirá um caractere de espaço entre os argumentos de dígito (por exemplo, 2 e 5 resultarão em $* com o valor citado 2 5 ), mas como podemos garantir que /dev/sda : nunca corresponderá, não importa nesta situação.

Para simplificar a linha de comando, você pode dispensar inteiramente o grep , assim:

blkid | sed -rn "s#/dev/(sda[$*]):"'.* UUID="([[:alnum:]]+)".*#\t#p'
    
por 29.09.2017 / 15:34