Filtragem avançada de arquivos

3

Eu tenho 3 pastas distintas: histórico, caixa de entrada, backup.

Eu preciso copiar todos os arquivos de 'history' para 'inbox', somente se eles não estiverem presentes em 'backup'.

Como fazer isso?

    
por Alban Soupper 28.09.2012 / 10:12

2 respostas

3

Apenas um exemplo, existe alguma subpasta na história?

for x in history/*;
do
  [[ -f backup/"$(basename "$x")" ]] || cp "$x" inbox
done

Esse script percorrerá todos os arquivos possíveis na pasta history e extrairá o nome base dele (por exemplo, o nome de base de / bin / ls is ls) e verificará se o arquivo existe na pasta de backup; se não, faça o procedimento de cópia.

    
por 28.09.2012 / 10:15
0

Esse script simples funciona apenas se os três diretórios não contiverem subdiretórios (um algoritmo recursivo mais complicado seria necessário para lidar com esse caso).

A resposta de Warlock é boa, mas a vantagem de um script como esse sobre o one-liner de Warlock é que usando xargs não usamos uma instância de cp para cada arquivo que copiamos. Nós apenas bifurcamos uma instância de cp para cada vez que o xargs gera uma linha de comando que preenche o limite de comprimento da linha de comando do shell. Isso tende a ser enorme em sistemas modernos, então é bem provável que nós rodássemos apenas uma instância de cp no total, mesmo para centenas ou possivelmente milhares de arquivos no histórico /

#! /bin/sh

# use tempfile(1) if available, otherwise use:
# EXCLUDEFILE="/tmp/excl.$$"
EXCLUDEFILE=$(tempfile -p excl)

# generate an exclude file, changing backup/ to history/    
find  backup/ -type f | sed -e 's:^backup/:history/:' > "$EXCLUDEFILE"

find history/ -type f -print0 | \
  grep -z -Z -F -v -x -f "$EXCLUDEFILE" | \
  xargs -0r -i{} cp {} inbox/

rm "$EXCLUDEFILE"

FYI, a forma longa das opções do grep usadas aqui são:

grep --null-data --null --fixed-strings --invert-match \
      --line-regexp --file "$EXCLUDEFILE"

e uma forma ainda mais compacta é:

grep -zZFvxf "$EXCLUDEFILE"

A maioria das opções é comumente usada ou autoexplicativa, mas três podem exigir alguma explicação:

-z ou --null-data informa ao grep que espera uma entrada terminada com nulo (de find -print0 )
-Z ou --null informa ao grep a saída de linhas com terminação nula (para canalizar para xargs -0 ) % -x ou --line-regexp diz ao grep para corresponder apenas em todas as linhas completas

    
por 28.09.2012 / 10:53