Как процессы могут устранять escape-коды, когда их вывод передается по конвейеру?

Вот рекурсивный подход, который не требует от вас заранее знать имена файлов tar-архивов. Поместите файл в каталог, в котором больше ничего нет. Затем, предполагая, что все tar-архивы, содержащиеся в родительском архиве, имеют расширение .tar, вы можете просто выполнить:

file=(*tar); while [[ -e $file ]]; do tar xf "$file"; rm "$file"; file=(*tar); done

Пояснение

  • file=(*tar);:установите переменную $fileтак, чтобы она содержала имя файла. Должен быть только один файл, соответствующий глобусу *tarв каталоге, в котором вы его запускаете.
  • while [[ -e $file ]]; do:пока $fileсуществует...
  • tar xf $file; rm "$file"; file=(*tar);:разархивируйте текущее значение $file, затем удалите только что извлеченный tar-архив и, наконец, установите переменную $fileна имя нового, пока единственного, tar-файла в каталоге.

А вот еще более прямой подход(спасибо @kusalananda!). Я сделал архив tarс помощью этих команд:

$ cat file 
This is the text!
$ file=file; for i in {1..1000}; do tar cf $i.tar $file; file=$i.tar; done

Итак, это файл с именем file, который содержит текст This is the text!\n. fileбыл смолен 1000 раз, и теперь у нас есть 1000.tar. Мы можем распечатать исходный текст с помощью:

$ awk -F'\0' '/[^\0]/{print $(NF)}' 1000.tar 
This is the text!

Обратите внимание, что на самом деле это не оригинальный текст. Исходная новая строка была съедена tar, но заменена на awk. Чтобы получить реальное значение из архива, вам нужно (последнее $вот моя подсказка, новой строки не было):

$ awk -F'\0' '/[^\0]/{printf "%s", $NF}' 1000.tar 
This is the text!$

В этом конкретном случае я также смог воссоздать имя файла, сказав awkнапечатать последнее поле ($NF),и 438-е поле перед последним:

awk -F'\0' '/[^\0]/{print $(NF) >$(NF-438)}' 1000.tar 

Это создало новый fileс содержимым оригинала. То же самое, что извлечение. Однако я не знаю, является ли -428магическим числом. tar, по-видимому, добавляет в свой архив несколько NULL, поэтому я обнаружил это, запустив:

$ awk -F'\0' '{for(i=1;i<=NF;i++){ if($i ~ /file/){print i,NF-i}}}' 1000.tar 
434674 438

Это подсказало мне, что поле 434674 имеет содержимое file, а это 438 полей до последнего.

Если ваш awkподдерживает gsub, вы, вероятно, можете сделать его более общим с помощью:

awk -F'\0' '/[^\0]/{gsub(/\0+/,"\0"); print $NF > $(NF-11)}' 1000.tar 

0
01.11.2020, 20:57
1 ответ

Чтение man isattyилиhttps://linux.die.net/man/3/isatty

isatty - test whether a file descriptor refers to a terminal
2
18.03.2021, 22:53

Теги

Похожие вопросы