Precisa de um caminho absoluto para cada linha de um arquivo de texto usando o shell script [closed]

0

Eu tenho um arquivo de texto com uma lista de arquivos .XML.

Eu preciso de um caminho absoluto de cada XML no arquivo.

Tentei seguir o shell script, mas depois de muita tentativa, o comando find não está funcionando dentro da tag do.

    #!/bin/sh
    NAMES='cat list2.txt'
    for NAME in $NAMES; 
   do
     echo "$NAME"
     find $PWD -type f -name "$NAME"
   done
    
por sayali 28.07.2017 / 08:01

6 respostas

2

Um loop é o caminho errado para resolver o problema. O rastreamento da árvore de diretórios para cada arquivo seria ineficiente. Você deseja rastrear o diretório apenas uma vez para arquivar todos os arquivos. Como com:

find "$PWD" -type f -print0 | awk -F / '
   !list_processed {names[$0]; next}
   $NF in names' list.txt RS='
find "$PWD" -type f -print0 | awk -F / '
   !list_processed {names[$0]; next}
   $NF in names' list.txt RS='%pre%' list_processed=1 -
' list_processed=1 -

Isso assume que list.txt contém uma lista de nome de arquivo (não caminho), um por linha.

    
por 28.07.2017 / 23:35
1

Seu código tem um bug, sua iteração está errada.

Eu usaria dessa forma na iteração:

#!/bin/sh
while IFS= read -r NAME; do
  echo "$NAME"
  find "$PWD" -type f -name "$NAME"
done <list.txt
    
por 28.07.2017 / 08:31
0

A variável PWD não está definida
Adicione antes que o ciclo comece | PWD=<path>

    
por 28.07.2017 / 08:20
0

Aqui está uma maneira alternativa de resolver o problema. Talvez assim funcione para você. Isso só chama uma vez, tornando muito mais rápido e eficiente.

stackoverflow.sh

#!/bin/sh

declare -a NAME_LIST=('cat list2')
#declare -i LIST_SIZE=${#NAME_LIST[*]}
declare EXPRESSION="find ${PWD} "

# build up the find command
for name in ${NAME_LIST[@]}; do
    if test ${NAME_LIST[0]} = ${name}; then
        EXPRESSION+="-type f -and -name $name "
    else
        EXPRESSION+="-or -type f -and -name $name "
    fi
done

eval $EXPRESSION

Na minha versão aprimorada, $EXPRESSION é igual a:

find /Users/charlie -type f -and -name one -or -type f -and -name two -or -type f -and -name three -or -type f -and -name four -or -type f -and -name five -or -type f -and -name six -or -type f -and -name seven -or -type f -and -name eight

Claro, o seu código original funciona bem para mim no bash no OSX (que tem o mesmo comando find que você faz no linux). Obviamente, como você também está repetindo o nome do arquivo (e não o caminho), a saída será uma lista dos arquivos e dos caminhos.

A única coisa que eu acho pode estar causando problemas é se o seu arquivo é codificado em unicode e os próprios nomes de arquivos reais não têm unicode. Caso contrário, imprime o caminho absoluto para o arquivo.

stackoverflow.sh:

#!/bin/sh

NAMES='cat list2'

for name in $NAMES; do
  echo $name >&2
  find $PWD -type f -name $name
done

Executando o programa:

$ charlie on macbook in ~
❯❯ cat list2
one
two
three
four
five
six
seven
eight

$ charlie on macbook in ~
❯❯ ./stackoverflow.sh
one
/Users/charlie/one
two
/Users/charlie/src/web/two
three
/Users/charlie/misc/three
four
/Users/charlie/four
five
/Users/charlie/Documents/five
six
/Users/charlie/Documents/Ideas/six
seven
/Users/charlie/seven
eight
/Users/charlie/Documents/eight

$ charlie on macbook in ~
❯❯ ./stackoverflow.sh
/Users/charlie/one
/Users/charlie/src/web/two
/Users/charlie/misc/three
/Users/charlie/four
/Users/charlie/Documents/five
/Users/charlie/Documents/Ideas/six
/Users/charlie/seven
/Users/charlie/Documents/eight

$ charlie on macbook in ~
❯❯ ./stackoverflow.sh 2>stderr-output
/Users/charlie/one
/Users/charlie/src/web/two
/Users/charlie/misc/three
/Users/charlie/four
/Users/charlie/Documents/five
/Users/charlie/Documents/Ideas/six
/Users/charlie/seven
/Users/charlie/Documents/eight

$ charlie on macbook in ~
❯❯ cmp list2 stderr-output

$ charlie on macbook in ~
❯❯ echo $?
0
    
por 29.07.2017 / 02:38
0

Obrigado por todas as suas respostas.
Problema foi resolvido. :)
Pode haver algum problema no arquivo de texto que estou passando, acabei de criar um novo arquivo de texto e copiar todos os dados para ele.

Passar este novo arquivo para loop funciona bem com o meu próprio código como:

#!/bin/sh
NAMES='cat myNewList.txt'
for NAME in $NAMES; 
 do
  find $PWD -type f -name "$NAME"
 done
    
por 31.07.2017 / 07:21
0
for NAME in $(cat list2.txt); do readlink -e $NAME; done
    
por 29.07.2017 / 05:45

Tags