Tarieren Sie eine Liste von Dateien ohne ihre Verzeichnisstruktur

Tarieren Sie eine Liste von Dateien ohne ihre Verzeichnisstruktur

Angenommen, ich mache Folgendes:

tar cvf allfiles.tar $(<mylist.txt)

Undmeineliste.txtenthält Folgendes:

/tmp/lib1
/tmp/path2/lib2
/path3/lib3

Wie tarnt man die Dateien, so dass das Tarball nur

lib1
lib2
lib3

ohne jegliche Verzeichnisstruktur?


Normalerweise wird die Verwendung -Cvon Optionen empfohlen (--directoryReferenz,Referenz), aber es gibt mehrere Verzeichnisse, also funktioniert das nicht. Außerdem --xformsieht es so aus, als ob es ein festes Muster erfordert (Referenz), die wir nicht haben.

Antwort1

Das --xformArgument akzeptiert eine beliebige Anzahl von sedErsatzausdrücken, die sehr leistungsfähig sind. Verwenden Sie in Ihrem Fall ein Muster, das bis zum letzten auf alles zutrifft /, und ersetzen Sie es durch nichts:

tar cvf allfiles.tar --xform='s|.*/||' $(<mylist.txt)

Hinzufügen, --show-transformed-namesum die neuen Namen anzuzeigen.

Beachten Sie, dass diese Ersetzung für alle Dateinamen gilt, nicht nur für die in der Befehlszeile angegebenen. Wenn Sie also beispielsweise eine Datei haben /a/b/cund Ihre Liste nur angibt /a, ist der endgültige Dateiname nur cund nicht b/c. Sie können immer expliziter sein und eine genaue Liste der Ersetzungen angeben, z. B. in Ihrem Fall

--xform='s|^tmp/path2/||;s|^tmp/||;s|^path3/||'

Beachten Sie, dass der Anfangsbuchstabe /von tar entfernt wird (es sei denn, Sie verwenden -P), sodass er in den obigen Ausdrücken fehlt. Außerdem muss die Liste der Verzeichnisse sortiert werden, sodass die längste Übereinstimmung zuerst gefunden wird, sonst wird tmp/path2/keine Übereinstimmung gefunden, da tmp/sie bereits entfernt wurde. Sie können die Erstellung dieser Liste jedoch automatisieren, z. B.:

--xform="$(sed <mylist.txt 's|[^/]*$||; s|^/||; s:.*:s|^&||;:' | sort | tr -d '\n')"

Antwort2

Mit GNU tarkönnen Sie es -Cab sofort verwenden, wann und so oft Sie möchten.

$ tree
.
├── 1
│   └── aaa
├── 2
│   └── bbb
└── 3
    └── ccc



# Caveat: the directory change is always relative to directory tar is using *at
# that time*, so the following doesn't work:
$ tar -cf foo.tar -C 1 aaa -C 2 bbb -C 3 ccc  
tar: 2: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

$ tar -cf foo.tar -C 1 aaa -C ../2 bbb -C ../3 ccc

$ tar tf foo.tar
aaa
bbb
ccc


# You can avoid the special case for the first directory by always specifying
# an absolute path:
$ tar -cf foo.tar -C $(pwd)/1 aaa -C $(pwd)/2 bbb -C $(pwd)/3 ccc



# Now let's create that automatically from your file:
$ cat mylist.txt
/tmp/1/aaa
/tmp/2/bbb
/tmp/3/ccc

$ while read -r line; do printf '-C %s %s ' $(dirname "$line") $(basename "$line") ; done < mylist.txt
-C /tmp/1 aaa -C /tmp/2 bbb -C /tmp/3 ccc 

# That looks about right. Let's use it in our tar command:
$ tar -cvf foo.tar $(while read -r line; do printf '-C %s %s ' $(dirname "$line") $(basename "$line") ; done < mylist.txt)
aaa
bbb
ccc

verwandte Informationen