Копировать только файлы и только строки, содержащие строку, сохраняя структуру каталогов

Копировать только файлы и только строки, содержащие строку, сохраняя структуру каталогов

Допустим, у меня есть каталог, содержащий другие каталоги и файлы. Я хочу найти строку в каждом файле и скопировать только соответствующие строки в другое место, сохраняя при этом структуру каталога.

Например, скажем, у меня есть такая структура

dir
  subdir1
     file1.txt
  subdir2
     file2.txt

и

file1.txt:

abc

def

и

file2.txt:

ghi

Теперь я хочу получить только совпадающие строки из файлов, которые содержат «de», поэтому желаемый результат должен выглядеть следующим образом:

dir
  subdir1
     file1.txt
  subdir2

и

file1.txt

def

решение1

С GNU find(1), xargs(1), и grep(1):

  • продублируйте структуру каталогов:

    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
    
  • копировать файлы по заданному шаблону:

    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)
    
  • восстановите разрешения, предполагая, что это Linux и что у вас нет имен файлов со встроенными символами новой строки:

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

Связанный контент