Copie somente arquivos e apenas linhas contendo uma string preservando a estrutura de diretório

3

Digamos que eu tenha um diretório que contenha outros diretórios e arquivos. Eu quero procurar uma seqüência de caracteres em cada arquivo e copie apenas as linhas correspondentes para outro local, preservando a estrutura de diretórios.

Por exemplo, digamos que eu tenha essa estrutura

dir
  subdir1
     file1.txt
  subdir2
     file2.txt

e

file1.txt :

abc

def

e

file2.txt :

ghi

Agora quero obter apenas as linhas correspondentes dos arquivos que contêm 'de', portanto, o resultado que desejo deve ficar assim:

dir
  subdir1
     file1.txt
  subdir2

e

file1.txt

def
    
por Miroslav Sabo 02.10.2016 / 18:33

1 resposta

2

Com o GNU find(1) , xargs(1) e grep(1) :

  • duplique a estrutura de diretórios:

    src=/path/to/source
    dest=/other/path/to/destination
    pat='some_grep_pattern'
    
    cd "$dest"
    find "$src" -type d ! -path "$src" -printf '%P
    cd "$src"
    grep -rlZ "$pat" | \
        (cd "$dest"; \
        xargs -0 sh -c ' \
            while [ $# -ne 0 ]; do \
                grep "$pat" "$src/$1" >"$1"; \
                touch -r "$src/$1" >"$1"; \
                shift; \
            done' sh)
    
    ' | xargs -0 mkdir -p
  • copie os arquivos com o padrão fornecido:

    cd "$src"
    getfacl -RPe . | (cd "$dest"; setfacl --restore=-)
    
  • restaurar permissões, assumindo o Linux, e assumindo que você não tem nomes de arquivos com novas linhas embutidas:

    src=/path/to/source
    dest=/other/path/to/destination
    pat='some_grep_pattern'
    
    cd "$dest"
    find "$src" -type d ! -path "$src" -printf '%P
    cd "$src"
    grep -rlZ "$pat" | \
        (cd "$dest"; \
        xargs -0 sh -c ' \
            while [ $# -ne 0 ]; do \
                grep "$pat" "$src/$1" >"$1"; \
                touch -r "$src/$1" >"$1"; \
                shift; \
            done' sh)
    
    ' | xargs -0 mkdir -p
por 02.10.2016 / 19:54