Как я могу распаковать gz файлы в случайных каталогах и хранить распакованные файлы в тех тех же каталогах?

Существует несколько методов, описанных в Wiki Arch. Самая легкая версия состоит в том, чтобы, вероятно, использовать perl-cpanplus-dist-arch, который, после установки и выполнения установки с setupdistarch может установить модули жемчуга как pacman пакеты с cpanp -i Your::Module::Name как описано в его документации.

3
09.05.2013, 09:55
4 ответа

Хотя можно проанализировать вывод от a find необходимо заботиться о пробелах и т.д. К сожалению, gunzip не имеет a --keep/-k флаг для хранения (как bzip2 и xz действительно имейте).

Если сделал бы маленький сценарий gunzipkeep это берет один параметр (gzipped файл) и делает распаковку, поместило тот сценарий где-нибудь в Ваш $PATH и называет его с:

find /opt/fooapp/foosubdirectory -name "foo.ext.gz" -print0 | xargs -0 --norun-if-empty --max-args 1 gunzipkeep

Сценарий мог быть чем-то как:

#!/bin/bash
inname=$1
outname=${inname%.gz}

gunzip -c "$inname" > "$outname"
5
27.01.2020, 21:13
  • 1
    Спасибо Anthon, но я не совсем следую за Вами на части сценария. Не был бы сценарий с gunzip все еще вытирать исходный gz файл? –  Mike B 09.05.2013, 10:05
  • 2
    я добавил сценарий, он включает -c опция как Вы использовала его, таким образом, это сохраняет оригинал. Важный сценарии разворачивает отдельный аргумент для Вас. Вы могли изменить его так, чтобы это сделало для цикла и удалило --max-args аргумент xargs для эффективности, но это, вероятно, незначительно по сравнению со временем gunzip, берет –  Anthon 09.05.2013, 10:12

Трудно сделать это, не используя сценарий помощника (или функция удара), как сделано в другом ответе, но не невозможное. Сюда использование -execdir опция find и некоторые bash расширение параметра.

find /opt/fooapp/foosubdirectory -name '*.gz' -execdir /bin/bash -c 'pwd ; echo ${0%.gz}; cp ${0} ${0%.gz}.tmp.gz ; gunzip ${0%.gz}.tmp.gz ; mv ${0%.gz}.tmp ${0%.gz}' {} \;

[редактирование] ПРИМЕЧАНИЕ: Вам нужна последняя версия bash (для этого конкретного параметра exparsion), некоторые более старые версии не имеет этого функциями. Я протестировал это на V 3.2.x

[Редактирование] NOTE2: -execdir выражение, как далеко я знаю, присутствует в GNU find (и другие современные реализации), но не в более старые. Я testet это на GNU находит v 4.2.x

Тот же rewitten для удобочитаемости и комментария:

find /opt/fooapp/foosubdirectory 
     -name '*.gz'
     -execdir /bin/bash -c '_bash_command_string_ ' {} \;
# This ^ will run bash from the subdirectory containing the matched file

  _bash_command_string_  --> 
      pwd ;                       # we are working in this subdir 
      echo ${0%.gz};              # this is matched filename (minus final .gz)
      cp ${0} ${0%.gz}.tmp.gz ;   # copy the .gz file as .tmp.gz
      gunzip ${0%.gz}.tmp.gz ;    # gunzip the .tmp.gz as .tmp
      mv ${0%.gz}.tmp ${0%.gz}    # rename .tmp as matched filename (minus final .gz)

Это решение интересно как умный взлом, но вероятно слишком сложное, чтобы использоваться в практике.

Посмотрите Ссылку Bash - Расширение Параметра Shell, поиск ${parameter%word} .

1
27.01.2020, 21:13

С ударом ≥4, выполненный shopt -s extglob сделать **/ каталоги пересечения рекурсивно. (Остерегайтесь этого, это пересекает символьные ссылки на каталоги. В zsh Вам не нужна никакая специальная установка, и **/ не убывает в символьные ссылки, но ***/ делает.) Затем простой цикл достаточен:

err=
for z in **/*.gz; do
  gunzip <"$z" >"${z%.gz}" &&
  touch -r "$z" "${z%.gz}" ||    # if you want to retain the file's modification time
  err=1
done
if [ -n "$err" ]; then echo >&1 'Watch out, there were errors!'; fi

Только с POSIX sh, вызовите оболочку от find. Более трудно извлечь ошибочное состояние — проверка, если команда производит что-нибудь на stderr.

find . -name '*.gz' -exec sh -c '
  for z do gunzip <"$z" >"${z%.gz}" && touch -r "$z" "${z%.gz}"; done
' _ {} +
1
27.01.2020, 21:13
find . -name \*.gz | parallel gzip -dc {} \> {.}
  • {.} входная строка без расширения
  • Разделитель по умолчанию является просто переводом строки
find . -name \*.gz | while read f; do gzip -dc "$f" > "${f%.gz}"; done
  • Добавить IFS= или -r если входные строки могут запуститься или закончиться символами в IFS или если они могут содержать обратные косые черты
0
27.01.2020, 21:13

Теги

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