¿Cómo puedo reparar un file tar donde stderr se mezcló con stdout?

Tengo un file tar que estoy tratando de reparar. El problema es que la stderr de tar se mezcló con su stdout , por lo que el file se ve así:

 % head android-1435613730.tar tar: removing leading '/' from member names factory/0000775000175100017510000000000007033241671011512 5ustar radioradiofactory/ factory/lost+found/0000700000000000000000000000000000000000000013242 5ustar rootrootfactory/lost+found/ tar: /factory/lost+found: Permission denied factory/wifi/0000770000175000017510000000000007033241625012667 5ustar systemradiofactory/wifi/ tar: /factory/wifi: Permission denied factory/imei/0000775000175100017510000000000007033241600012425 5ustar radioradiofactory/imei/ tar: can't open '/factory/nv_data.bin': Permission denied tar: can't open '/factory/nv_data.bin.md5': Permission denied factory/bluetooth/0000755000175100017510000000000007033241674013520 5ustar radioradiofactory/bluetooth/ 

Intenté eliminar los posts de error, así:

 % grep --color=never -v --binary-file=text '^tar:.*$' android-1435613730.tar | tar -tv drwxrwxr-x radio/radio 0 1999-12-31 16:00 factory/ tar: Skipping to next header drwx------ install/all_a124 0 2015-06-29 13:51 acct/uid/50124/ tar: Skipping to next header tar: Exiting with failure status due to previous errors 

Pero como puede ver, esto produce un error. (Te ahorraré el volcado de files de datos binarys horrible, a less que realmente se necesite).

También debo señalar que este file es bastante grande (6,7 GB) y no tengo tanto núcleo o intercambio disponible.

El tarball está siendo desatado con el mismo tar que se usó para crearlo, GNU Tar 1.27.1.

Por sugerencia de @kos, intenté usar Perl:

 % <android-1435613730.tar perl -pe 's/\n?tar: [^\n]*\n//sg' | tar -tv drwxrwxr-x radio/radio 0 1999-12-31 16:00 factory/ tar: Skipping to next header drwx------ install/all_a83 0 2015-06-29 13:55 acct/uid/50083/ tar: Skipping to next header tar: Exiting with failure status due to previous errors 

Para su comodidad, aquí hay un script para recrear el problema:

 #!/bin/sh TMPDIR=$(mktemp -d) cd $TMPDIR for i in test test2 test3; do mkdir $i echo $i > $i/$i done chmod 000 test2/test2 chmod 000 test3 tar -c test* > broken.tar 2>&1 echo "Created corrupt tarball in $TMPDIR" 

Aunque en mi tarball los errores se mezclan en el medio, que no puedo reproducir aquí.

Related of "¿Cómo puedo reparar un file tar donde stderr se mezcló con stdout?"

Siempre que stdout y stderr estén en línea amortiguada y las líneas de una de las dos sean siempre identificables, mezclarlas no es un problema: considere la salida de un progtwig en el que tanto stdout como stderr tienen búfer de línea, y donde stderr es fácil Spottable:

 $ cat file xxxxxxxxxx tar: ---------- yyyyyyyyyy tar: ---------- zzzzzzzzzz tar: ---------- 

La extracción de cualquiera de los dos usando grep no es un problema:

 $ < file grep -v ^tar xxxxxxxxxx # stdout line 1 yyyyyyyyyy # stdout line 2 zzzzzzzzzz # stdout line 3 $ < file grep ^tar tar: ---------- # stderr line 1 tar: ---------- # stderr line 2 tar: ---------- # stderr line 3 

Sin embargo, considere el caso en el que en algún punto el comportamiento de almacenamiento en búfer de stdout cambia, por ejemplo, sin búfer:

 x tar: ---------- xxxxxxxxxyyy tar: ---------- yyyyyyyzzzzz tar: ---------- zzzzz 

La extracción de stdout usando grep es un problema:

 $ < file grep -v ^tar x # wrong stdout line 1 xxxxxxxxxyyy # wrong stdout line 2 yyyyyyyzzzzz # wrong stdout line 3 zzzzz # wrong stdout line 4 

Pruebe esto en su lugar:

 < file perl -0777pe 's/\n?tar: [^\n]*\n//g' > newfile 

Que, excluyendo casos [borde], debería extraer la stdout original del file:

 $ < file perl -0777pe 's/\n?tar: [^\n]*\n//g' xxxxxxxxxxyyyyyyyyyyzzzzzzzzzz