Как grep для шаблона в файлах в архиве tar без заполнения дискового пространства
У меня есть архив tar, который очень большой ~ 5GB.
Я хочу grep для шаблона для всех файлов (а также распечатать имя файла, который имеет шаблон ) в архиве, но не хочу заполнять дисковое пространство, извлекая архив.
в любом случае я могу это сделать?
Я пробовал это, но это не дает мне имена файлов, которые содержат шаблон, только соответствующие строки:
tar -O -xf test.tar.gz | grep 'this'
tar -xf test.tar.gz --to-command='grep awesome'
также Где эта функция tar документирована? тест tar xf.tar $FILE
7 ответов
вот мой взгляд на это:
while read filename; do tar -xOf file.tar "$filename" | grep 'pattern' | sed "s|^|$filename:|"; done < <(tar -tf file.tar | grep -v '/$')
вырвалось для объяснения:
-
while read filename; do
-- это петля... -
tar -xOf file.tar "$filename"
-- это извлекает каждый файл... -
| grep 'pattern'
-- вот где вы положили ваш шаблон... -
| sed "s|^|$filename:|";
- добавьте имя файла, так что это выглядит как grep. Посолить по вкусу. -
done < <(tar -tf file.tar | grep -v '/$')
-- конец цикла, получить список файлов, как fead для вашегоwhile read
.
один оговорка: это ломается, если у вас есть или бары (|
) в именах файлов.
Хм. На самом деле, это делает хорошую небольшую функцию bash, которую вы можете добавить к своему :
targrep() {
local taropt=""
if [[ ! -f "" ]]; then
echo "Usage: targrep pattern file ..."
fi
while [[ -n "" ]]; do
if [[ ! -f "" ]]; then
echo "targrep: : No such file" >&2
fi
case "" in
*.tar.gz) taropt="-z" ;;
*) taropt="" ;;
esac
while read filename; do
tar $taropt -xOf "" \
| grep "" \
| sed "s|^|$filename:|";
done < <(tar $taropt -tf | grep -v '/$')
shift
done
}
кажется, что никто не выложил это простое решение, которое обрабатывает архив только один раз:
tar xzf archive.tgz --to-command \
'grep --label="$TAR_FILENAME" -H PATTERN ; true'
здесь tar
передает имя каждого файла в переменной (см. документы) и используется grep
печатать его с каждым совпадением. Также true
добавляется, так что tar
не жалуется на невозможность извлечения файлов, которые не совпадают.
вот функция bash, которая может работать для вас. Добавьте к вашему ~/.bashrc
targrep () {
for i in $(tar -tzf ""); do
results=$(tar -Oxzf "" "$i" | grep --label="$i" -H "")
echo "$results"
done
}
использование:
targrep archive.tar.gz "pattern"
Это невероятно хаки, но вы можете злоупотреблять tar в -v
возможность обработки и удаления каждого файла по мере его извлечения.
grep_and_delete() {
if [ -n "" -a -f "" ]; then
grep -H 'this' -- "" </dev/null
rm -f -- "" </dev/null
fi
}
mkdir tmp; cd tmp
tar -xvzf test.tar.gz | (
prev=''
while read pathname; do
grep_and_delete "$prev"
prev="$pathname"
done
grep_and_delete "$prev"
)
tar -tf test.tar.gz | grep -v '/$'| \
xargs -n 1 -I _ \
sh -c 'tar -xOf test.tar.gz _|grep -q <YOUR SEARCH PATTERN> && echo _'
попробуй:
tar tvf name_of_file |grep --regex="pattern"
опция t проверит tar-файл без извлечения файлов. V многословен, а f печатает имена файлов. Это сэкономит вам место на жестком диске.
может поможет
zcat log.tar.gz | grep -a -i "string"
zgrep -i "string" log.tar.gz
http://www.commandlinefu.com/commands/view/9261/grep-compressed-log-files-without-extracting