Valor de acesso de cada item iterado bash

0

Eu tenho um código que percorre um diretório e encontra todos os arquivos com uma extensão .xz

O problema é que não consigo descobrir como acessar cada arquivo iterado com .xz , em vez de obter o valor de ROOTPATH . o que estou fazendo errado?

ROOTPATH='/home/user/path'
for file in "$ROOTPATH"; do
find $PWD -name '*.xz'
echo "file is $file"
done

Isso gera os arquivos como:

/home/user/path/file1.tar.xz
/home/user/path/file2.tar.xz

, a parte echo é impressa:

file is /home/user/path

como posso acessar cada um dos itens iterados, por exemplo,

/home/user/path/file1.tar.xz
/home/user/path/file2.tar.xz

obrigado

    
por john jones 12.10.2017 / 20:08

3 respostas

1

Você não está usando o glob *.xz para corresponder aos arquivos no caminho, quando você faz isso, você nem precisa do comando find . Apenas faça

ROOTPATH="/home/user/path"
for file in "$ROOTPATH"/*.xz; do
    [ -f "$file" ] || continue
    printf "%s\n" "$file"
done

O *.xz é um padrão glob padrão para corresponder a todos os arquivos com a extensão .xz no caminho especificado. O [ -f "$file" ] || continue é apenas uma verificação de sanidade necessária para manipular a saída do loop quando o glob retorna um resultado vazio, ou seja, quando nenhum arquivo é encontrado.

Se por acaso você também estiver procurando por arquivos sob os subdiretórios, ative a opção de globbing de shell estendido globstar para ativar a correspondência recursiva nos nomes de arquivos e faça

shopt -s globstar nullglob
for file in "$ROOTPATH"/**/*.xz; do
    printf "%s\n" "$file"
done
    
por 12.10.2017 / 20:13
1

Você não deve iterar sobre o resultado de find , consulte Por que o looping é uma má prática de saída?

Em vez disso, chame seu script de dentro de find :

find "$ROOTPATH" -type f -name '*.xz' \
    -exec sh -c 'for n; do printf "Got name %s\n" "$n"; done' sh {} +

ou, para chamar um script separado:

find "$ROOTPATH" -type f -name '*.xz' \
    -exec /some/path/script.sh {} +

O script pode se parecer com:

#!/bin/sh

for name; do
    # do something with "$name"
done

O script, seja incorporado com sh -c (ou bash -c se você precisar de bash ) ou separado, será chamado nesse caso com o máximo de .xz de arquivos (pode ser chamado várias vezes se o número de arquivos está na casa das centenas). O loop for name irá iterar sobre os nomes encontrados e você pode usar $name (corretamente citado, é claro) para fazer o que for necessário para os arquivos individuais.

    
por 12.10.2017 / 20:33
0

Use find no próprio ciclo:

ROOTPATH="/home/user/path"
for file in 'find $ROOTPATH -type f -name *.xz -print'
do
        echo "file is $file"
done
    
por 12.10.2017 / 20:19