Как 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