2017-02-10 2 views
1

Я хотел бы иметь скрипт, который сжимает все файлы (используя tar) в каталоге «logs» (песочница/tmp/logs). Не уверен, где я ошибаюсь, но он сжимает все файлы, каталог и путь. Который я не хочу. Я просто хочу сжать ТОЛЬКО файлы в «журнальных» каталогах. Любая помощь будет оценена.Только сжатые файлы

Вот мой код:

#!/bin/bash 

LOG_FILES="/Sandbox/tmp/logs" 

for file in ${LOG_FILES}/* ; do 
    tar -cvzf "${file}.tar.gz" "$file" 
done 

ответ

1

Я не совсем ясно, на что вы просите, но я думаю, что ваша проблема в том, что вы предоставляете слишком много информации о пути к дегтя. Допустим, у вас есть следующие файлы:

/Sandbox/tmp/logs/foo 
/Sandbox/tmp/logs/bar 
/Sandbox/tmp/logs/baz 

То, что вы должны в основном выполнять следующие команды:

tar -cvzf "/Sandbox/tmp/logs/foo.tar.gz" "/Sandbox/tmp/logs/foo" 
tar -cvzf "/Sandbox/tmp/logs/bar.tar.gz" "/Sandbox/tmp/logs/bar" 
tar -cvzf "/Sandbox/tmp/logs/baz.tar.gz" "/Sandbox/tmp/logs/baz" 

Обратите внимание, как все пути включены; tar пытается поддерживать пути в архиве, чтобы при извлечении tarball все было реконструировано именно так, как это было (например, если вы хотите сжать foo/bar.txt и baz.txt, при их извлечении вы, вероятно, захотите, чтобы bar.txt находился в подкаталоге foo).

Самый простой способ обойти это просто избавиться от путей ... меняющимися каталоги /Sandbox/tmp/logs вне цикла следует сделать трюк:

#!/bin/bash 

LOG_FILES="/Sandbox/tmp/logs" 

cd "${LOG_FILES}" 

for file in * ; do 
    tar -cvzf "${file}.tar.gz" "$file" 
done 

С, что вы будете в конечном итоге с следующие новые файлы:

/Sandbox/tmp/logs/foo.tar.gz 
/Sandbox/tmp/logs/bar.tar.gz 
/Sandbox/tmp/logs/baz.tar.gz 

Однако, теперь вы все еще в /Sandbox/tmp/logs, который может быть проблемой позже в сценарии. Чтобы обойти эту проблему вы можете использовать подоболочку:

#!/bin/bash 

LOG_FILES="/Sandbox/tmp/logs" 

(cd "${LOG_FILES}"; 
for file in * ; do 
    tar -cvzf "${file}.tar.gz" "$file" 
done) 

Теперь, все, что сказал, вы действительно не нужно использовать деготь для сжатия отдельных файлов. Вместо этого вы можете просто использовать gzip; вы сэкономите несколько байт, и gzip по умолчанию для создания файла прямо рядом с входом, так что вы можете избавиться от cd хлама:

#!/bin/bash 

LOG_FILES="/Sandbox/tmp/logs" 

for file in "${LOG_FILES}"/*; do 
    gzip -k "$file" 
done 

Который даст

/Sandbox/tmp/logs/foo.gz 
/Sandbox/tmp/logs/bar.gz 
/Sandbox/tmp/logs/baz.gz 

И gzip будет счастливо сжать несколько входов на несколько выходов, так что если вы хотите один лайнер вы можете просто пойти с

gzip -k "${LOG_FILES}"/* 

И, если у ou имеет параллельную установку GNU, вы можете сжимать файлы параллельно с чем-то вроде

parallel gzip -k ::: /Sandbox/tmp/logs/* 
Смежные вопросы