Copie solo archivos y solo líneas que contengan una cadena mientras conserva la estructura del directorio

Copie solo archivos y solo líneas que contengan una cadena mientras conserva la estructura del directorio

Digamos que tengo un directorio que contiene otros directorios y archivos. Quiero buscar una cadena en cada archivo y copiar solo las líneas coincidentes en otra ubicación preservando la estructura del directorio.

Por ejemplo, digamos que tengo esta estructura

dir
  subdir1
     file1.txt
  subdir2
     file2.txt

y

file1.txt:

abc

def

y

file2.txt:

ghi

Ahora quiero obtener sólo líneas coincidentes de los archivos que contienen 'de', por lo que el resultado que quiero debería verse así:

dir
  subdir1
     file1.txt
  subdir2

y

file1.txt

def

Respuesta1

Con GNU find(1), xargs(1)y grep(1):

  • duplicar la estructura del directorio:

    src=/path/to/source
    dest=/other/path/to/destination
    pat='some_grep_pattern'
    
    cd "$dest"
    find "$src" -type d ! -path "$src" -printf '%P\0' | xargs -0 mkdir -p
    
  • copiar archivos con el patrón dado:

    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)
    
  • restaure los permisos, asumiendo Linux y asumiendo que no tiene nombres de archivos con nuevas líneas incrustadas:

    cd "$src"
    getfacl -RPe . | (cd "$dest"; setfacl --restore=-)
    

información relacionada