3

Say I have a directory that contains other directories and files. I want to search for a string in each file and copy only the matching lines to another location while preserving directory structure.

For example, say I have this structure

dir
  subdir1
     file1.txt
  subdir2
     file2.txt

and

file1.txt:

abc

def

and

file2.txt:

ghi

Now I want to get only matching lines from the files that contain 'de', so the outcome I want should look like this:

dir
  subdir1
     file1.txt
  subdir2

and

file1.txt

def
  • This is more a programming question (be it in bash) than a Linux question: you may consider posting it on StackOverflow instead. (However I won't flag anything here as some people will think of a conditional grep-supported find to do just that there :) ). – JohnW Oct 2 '16 at 16:40
2

With GNU find(1), xargs(1), and grep(1):

  • duplicate the directory structure:

    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
    
  • copy files with the given pattern:

    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)
    
  • restore permissions, assuming Linux, and assuming you don't have filenames with embedded newlines:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.