Validando o formato do nome do arquivo no shell do linux

1

Eu estarei recebendo arquivos de dados em um diretório Linux.

Eu preciso validar que os nomes dos arquivos sigam o seguinte padrão "NNN-YYYYMMDD-NNNNNNNNN.pdf" onde

  • NNN significa valor numérico (0-9).
  • "AAAAMMDD" significa data válida. AAAA é o ano, MM é o mês (entre 1-12) e DD é o dia do mês (pode ter valores entre 01 a 31, dependendo do mês).
  • NNNNNNNN é um número numérico (isto é, apenas 0-9 permitido).

Qual utilitário (SED, AWK etc.) e como devo usar para validar o nome do arquivo.

    
por AlluSingh 07.07.2017 / 21:43

4 respostas

2

Isso testa todos os arquivos no diretório atual, usando o operador [[ do bash, em relação ao padrão:

  • início da string ^
  • 3 dígitos
  • -
  • 8 dígitos
  • -
  • 9 dígitos
  • .pdf
  • fim da string $
  • que os 8 dígitos do meio são avaliados para uma data válida de acordo com a data do GNU

Você pode ajustar as suposições acima com bastante facilidade.

for f in *
do
  [[ $f =~ ^([0-9][0-9][0-9])-([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])-([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]).pdf$ ]] && 
  date -d ${BASH_REMATCH[2]} &>/dev/null && 
  echo Valid: "$f"
done
    
por 07.07.2017 / 22:20
1

parece:

TOCHECK=( "01-20170228-12345678" "012-20170230-012345678" "01-20170228-12345678" "123-20170730-012345678" )

for CHECK in $(seq 0 $(( ${#TOCHECK[@]}-1 )) ); do
    PARTS=( $(echo ${TOCHECK[$CHECK]} | sed "s/-/ /g")   )   
    echo -ne "\nchecking "
    echo "\"${PARTS[@]}\""
    echo "\"${PARTS[0]}\""
    echo "\"${PARTS[1]}\""
    echo "\"${PARTS[2]}\""

    if echo ${PARTS[0]} | grep "[0-9]\{3\}" ; then
        echo first part ok
    fi

    if echo ${PARTS[2]} | grep "[0-9]\{9\}" ; then
        echo last part ok
    fi  

    date --date="${PARTS[1]}"
    RES=$?
    echo $RES
    if [ 0$RES -eq 0 ]; then
        echo date OK
    fi  
done

(apenas alguma ideia conceitual, é claro que será modificada)

    
por 07.07.2017 / 22:11
1

Não é suficiente usar regexps. A validação é de 2 etapas: correspondência de expressões regulares e validação de data. Aqui está uma implementação do Python:

from __future__ import print_function
import sys 
import re
import datetime

def validate(filename):
    match = re.match(r"[0-9]{3}-([0-9]{8})-[0-9]{8}\.pdf", filename)
    if not match:
        return False
    datestr = match.group(1)
    try:
        datetime.date(int(datestr[:4]), int(datestr[4:6]), int(datestr[6:8]))
    except ValueError:
        return False
    else:
        return True

if __name__ == "__main__":
    if validate(sys.argv[1]):
        print(":-)")
        sys.exit(0)
    else:
        print(":-(")
        sys.exit(1)

Uso: python validate.py FILE

É possível usar grep e date para fazer o mesmo.

    
por 07.07.2017 / 22:23
1

Uma solução básica, usando grep . Não faz o aspecto detalhado da verificação de data, em vez disso, apenas verifica se é numérico.

if ls|grep -vE '^[0-9]{3}-[0-9]{8}-[0-9]{8}\.pdf$'; then
    echo some bogus files found
else
    echo all good
fi
    
por 07.07.2017 / 22:50