Script Bash Shell Wildcard Pesadelo

0

Estou trabalhando em um script de shell para o trabalho que deve permitir-me encontrar um diretório baseado em um número de 5 ou 6 dígitos que um sistema nosso usa, e copiar um arquivo de dentro desse diretório. Eu faria isso manualmente, mas eu preciso obter mais de 3000 registros de cerca de 3 TB de dados disponíveis.

Aqui está o problema que estou correndo. Parte do meu script está usando find, e quando eu vou executá-lo, o script insere um '\ r' na frente do curinga que eu coloquei no script. Eu tentei escapar com um \, citando-o, mas nada que eu faça me permitirá usar o curinga neste comando. Eu citei meu código abaixo.

#!/bin/bash

export IFS="\n"

cat $1 | while read -r LINE
do
    #Change directory to root of necessary files.
    cd /volume1/Backup/CMS_Data/CLIENT\ DATA\ COPY/

    echo "Current Directory"
    pwd

    #Get directory needed based on current line
    CLAIM="$(find $LINE\*/documents/ -type d)"

    #Change to directory based on claim number.
    echo $CLAIM

done

Abaixo está o resultado que recebo.

find: '48668\r*/documents/': No such file or directory

Eu não consigo encontrar nada sobre qualquer \ r * escape ou como contornar isso. Alguma idéia do que está causando isso?

    
por Andrew Wallace 24.05.2018 / 22:45

3 respostas

0

Outra maneira de limpar os retornos de carro da entrada é aproveitar o recurso do comando read que apara espaços em branco iniciais e finais do que lê. Apenas redefina IFS (basicamente, a definição de espaço em branco do shell) para incluir \r , desta forma:

... while IFS=$' \t\n\r' read -r LINE ...

Observe que, como a definição de IFS é um prefixo do comando read , ela se aplica somente a esse comando e não atrapalha os outros itens (ou precisa ser restaurada ao normal mais tarde).

BTW, sua redefinição de IFS no começo é bastante problemática, já que a barra invertida não é tratada como uma fuga nessa situação específica, então você definiu com eficiência \ e n como os caracteres de espaço em branco . Isso pode ter realmente efeitos estranhos. Eu recomendo apenas deixar isso em paz.

Algumas outras recomendações: cat para ler o arquivo; é inútil. Apenas redirecione a entrada, assim:

while IFS=$' \t\n\r' read -r LINE
do
    ...
done <"$1"

Além disso, é quase sempre uma boa idéia colocar aspas duplas em torno de referências de variáveis (como fiz acima para $2 ) para evitar artefatos de análise estranhos. O mesmo vale para $LINE . Ah, e também recomendo evitar nomes de variáveis em maiúsculas; Há um monte deles com significados especiais, e é fácil reutilizar acidentalmente um deles e obter resultados estranhos. É muito mais seguro usar nomes de variáveis com letras maiúsculas ou minúsculas.

Por fim, recomendo sempre adicionar uma verificação de erro ao comando cd nos scripts, pois se ele falhar, o restante do script será executado em um local inesperado com resultados talvez bizarros. Algo parecido com isto:

cd /volume1/Backup/CMS_Data/CLIENT\ DATA\ COPY/ || {
    echo "Error changing directory to CLIENT DATA COPY; giving up" >&2
    exit 1
}
    
por 25.05.2018 / 08:12
0

O arquivo que você está passando como $1 tem \r\n newlines. Seu $IFS é \n , então \r permanece como o caractere final de $LINE .

Use dos2unix para converter o arquivo.

    
por 24.05.2018 / 22:54
0

Parece haver várias maneiras de corrigir isso. A maneira mais fácil seria corrigir a variável $ LINE para descartar qualquer caractere não numérico. Você pode fazer isso adicionando a seguinte linha antes da linha começar a CLAIM =

  LINE=${LINE//[!0-9]//}

Dependendo da sua entrada, você também pode precisar alterar a linha CLAIM para CLAIM="$ (encontrar $ LINE / * / documents / -type d)"

Uma solução alternativa seria alterar sua primeira linha para filtrar os retornos de carro na entrada - você poderia alterá-la para algo como

 tr -d "\r" < $1 | while read -r LINE
    
por 24.05.2018 / 23:12