Teste se os arquivos começam com certas letras e não contêm caracteres especiais, exceto para o período ao final da extensão do arquivo em um shell script

2

Eu tenho um script de shell que executa um loop for para executar um comando em vários arquivos de texto em uma pasta. Quero testar se os nomes desses arquivos começam com um conjunto específico de letras (NA, por exemplo) e não tenho caracteres especiais no arquivo (sem períodos, exceto antes de uma extensão de arquivo, '-s', _ _s, por exemplo). Eu sei como testar o nome completo de um arquivo, mas não sei como testar se parte dele tem esses caracteres ou como especificar o conteúdo de apenas letras e números, mas nenhum caractere especial, exceto o '.' em '.txt'. Como eu poderia fazer isso para que um comando seja executado somente em arquivos que atendam a esses requisitos? Eu sei que usaria uma declaração if, mas além disso eu não tenho certeza. Parece uma situação para usar curingas ou reg-exs.

    
por cluemein 08.07.2015 / 20:53

5 respostas

3

O código abaixo permitirá que você execute alguma ação nos arquivos de texto que começam com "NA", apenas com caracteres alfanuméricos e terminando com ".txt".

for f in /path/to/your/folder/*; do 
   if [[ ${f##*/} =~ NA[a-zA-Z0-9]*.txt ]]; then
      # perform some action on $f
   fi
done

Se você quiser permitir que seu arquivo comece com "N" ou "A" use:

for f in /path/to/your/folder/*; do 
    if [[ ${f##*/} =~ [N,A][a-zA-Z0-9]*.txt ]]; then
       # perform some action on $f
    fi
done
    
por 08.07.2015 / 21:16
1

Aqui um hack rápido:

#!/bin/bash
for i in *;
do
  if [ $(echo $i|cut -c 1-2) == "NA" ];
    then
    EXECUTE_COMMAND
  fi
done

Eu entendi sua pergunta corretamente?

    
por 08.07.2015 / 21:15
1

Você poderia usar o uso de globbing estendido se o seu shell for compatível, por exemplo

bash :

shopt -s extglob
for f in  NA*([[:alnum:]]).txt; do something; done

zsh :

setopt extendedglob
for f in  NA([[:alnum:]])#.txt; do something; done

em que *(...) e, respectivamente, (...)# significam zero ou mais ocorrências.

    
por 08.07.2015 / 22:23
1
for f in ./*
do    case ${f#??} in
      (*.*.*|*[!-_.[:alnum:]]*) ;;
      (NA*.txt)
          : do something w/ "$f"
      esac
done

A instrução case permite ramificar blocos de código para várias possibilidades. Embora eu faça a correspondência acima para 2 ou mais pontos ou um caractere não-traço-sublinhado-ponto-alfanumérico, não funciona, você é tão livre para colocar um bloco de código quanto qualquer outro lugar. case corresponde tanto quanto e assim que possível e, portanto, se você chegar à correspondência NA*.txt , será apenas porque o nome do arquivo que corresponde a esse padrão também não / em> corresponde ao padrão que veio antes.

E como eu disse, esta é uma declaração de ramificação, e então ...

for f in ./*
do    case ${f#??} in
      (*.*.*|*[!-_.[:alnum:]]*) ;;
      (NA*.txt)
           : do something w/ "$f.txt";;
      (NA*.pdf)
           : do something w/ "$f.pdf";;
      (FA*.txt)
           : do something w/ "$f";;
      (*)
           : do something w/ everything else
      esac
done

... é perfeitamente válido. Cada bloqueio condicional pode ser o tempo que você desejar - e as linhas novas e o restante são válidas dentro delas. Cada bloco condicional, mas o último deve ser delimitado com dois pontos e vírgulas, mas estes são opcionais para o último bloco condicional.

Quando o case é avaliado, cada padrão é avaliado por sua vez. Se uma correspondência for encontrada, nenhum dos seguintes padrões será avaliado - eles estão efetivamente em curto-circuito nesse caso.

    
por 08.07.2015 / 22:18
0

egrep deve fazer:

egrep 'NA[A-Z a-z 0-9]*\..{3,4}$'

Então ls /path/to/dir | egrep 'NA[A-Z a-z 0-9]*\..{3,4}$' listaria:

NAfoo.txt
NAbar1.jpeg
NA123baz.txt

mas excluiria:

aiNA1foo.txt
NA2foo_bar.jpeg
NAbar.baz.txt

E assim por diante.

    
por 08.07.2015 / 21:24