Combinando arquivos em um diretório e verificando

1

Eu tenho arquivos em um diretório (/ home / user / example) que preciso verificar e corresponder. Cada arquivo tem um arquivo de controle e dados. Eu quero verificar se para cada arquivo existe um arquivo correspondente do outro. Por exemplo, se example.ctl tiver uma correspondência com example.out ou example.out tem um arquivo correspondente com example.ctl.

Eu escrevi um loop for aninhado e com muitas instruções if else. Mas isso parecia ser muito complexo para uma verificação básica como essa. Eu queria ver se alguém tinha uma solução melhor.

Arquivos de exemplo no diretório:

example.ctl
example.out  
example_1.ctl
example_1.out  
example_2.ctl
example_2.out  
    
por Defcon 21.03.2018 / 19:21

4 respostas

1

Primeira variante

Ele percorre todos os nomes de arquivos e verifica cada arquivo, tem um par ou não e imprime uma mensagem correspondente.

for i in *; do
    base=${i%.*}
    if [ -e "${base}.out" -a -e "${base}.ctl" ]; then
        printf 'file "%s" has a pair\n' "$i"
    else
        printf 'file "%s" has not a pair\n' "$i"
    fi  
done

Segunda variante

Ele só é iterado por .ctl arquivos e a verificação faz com que o arquivo .ctl atual tenha um par - o arquivo .out . Então, ele imprime somente arquivos emparelhados, omitindo o resto - arquivos não pareados.

for i in *.ctl; do
    base=${i%.*}
    if [ -e "${base}.out" ]; then
        printf 'file "%s" has a pair "%s"\n' "$i" "${base}.out"
    fi
done
    
por 21.03.2018 / 21:23
2
comm <(basename -a -s.ctl *.ctl | sort) <(basename -a -s.out *.out | sort)

Ver comm(1) , normalmente os sinalizadores -12 listarão apenas os arquivos com os dois sufixos.

    
por 21.03.2018 / 21:22
0

Você está tentando detectar arquivos .ctl e .out ausentes, portanto, é necessário verificar as duas formas. Uma maneira fácil de fazer isso (se os nomes dos arquivos não contiverem caracteres especiais, incluindo espaços em branco, e contiverem apenas um único ponto) é para

  1. encontre todos os arquivos com find . -type f ,
  2. remova a extensão de cada um deles com cut --delimiter=. --fields=1 ,
  3. sort --unique para remover duplicatas,
  4. passeie por eles com while read name e, finalmente,
  5. verifique se cada um dos arquivos existe com [[ -e "${name}.ctl" ]] || echo "${name}.ctl" >&2 e o mesmo para .out.
por 21.03.2018 / 21:25
0

Você pode percorrer os arquivos e derivar os nomes de arquivos esperados para os arquivos de saída e controle. Depois de fazer isso, você pode verificar se ambos existem:

for item in *.out *.ctl
do
    base="${item%???}"
    out="$base.out" ctl="$base.ctl"
    [ -f "$out" -a ! -f "$ctl" ] && echo "$out is missing $ctl" >&2
    [ -f "$ctl" -a ! -f "$out" ] && echo "$ctl is missing $out" >&2
done
    
por 20.08.2018 / 22:36