Kopieren Sie nur Dateien und nur Zeilen, die eine Zeichenfolge enthalten, und bewahren Sie dabei die Verzeichnisstruktur auf.

Kopieren Sie nur Dateien und nur Zeilen, die eine Zeichenfolge enthalten, und bewahren Sie dabei die Verzeichnisstruktur auf.

Angenommen, ich habe ein Verzeichnis, das andere Verzeichnisse und Dateien enthält. Ich möchte in jeder Datei nach einer Zeichenfolge suchen und nur die übereinstimmenden Zeilen an einen anderen Speicherort kopieren, wobei die Verzeichnisstruktur erhalten bleiben soll.

Nehmen wir zum Beispiel an, ich habe diese Struktur

dir
  subdir1
     file1.txt
  subdir2
     file2.txt

Und

file1.txt:

abc

def

Und

file2.txt:

ghi

Jetzt möchte ich nur noch die übereinstimmenden Zeilen aus den Dateien erhalten, die „de“ enthalten. Das gewünschte Ergebnis sollte also folgendermaßen aussehen:

dir
  subdir1
     file1.txt
  subdir2

Und

file1.txt

def

Antwort1

Mit GNU find(1), xargs(1), und grep(1):

  • duplizieren Sie die Verzeichnisstruktur:

    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
    
  • kopiere Dateien mit dem angegebenen Muster:

    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)
    
  • Stellen Sie die Berechtigungen wieder her (unter der Annahme, dass es sich um Linux handelt und Sie keine Dateinamen mit eingebetteten Zeilenumbrüchen haben):

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

verwandte Informationen