Como posso extrair vários arquivos 7zip para pastas com os mesmos nomes no Linux?

1

Tenho cerca de 300 arquivos 7zip, cada um com vários arquivos, e nenhuma estrutura de diretório dentro dele.

Eu preciso extrair todos esses arquivos para pastas que correspondam ao respectivo arquivo.

Exemplo:

foo.7z e bar.7z

Extraia o conteúdo de foo.7z para /foo/
Extraia o conteúdo de bar.7z para /bar/

Eu tentei este script:

find . -name "*.7z" -type f| xargs -I {} 7z x -o{} {}

Mas isso resultou em:

can not open output file ./foo.7z/file.bin
Skipping    file.bin

O que estou fazendo de errado? Estou usando o Ubuntu Linux.

    
por Moses 12.11.2015 / 15:54

2 respostas

3

Você está tentando criar um diretório com o mesmo nome do arquivo. Isso não funciona: não pode haver duas entradas de diretório com o mesmo nome.

Uma maneira de corrigir isso é usar basename para remover a extensão .7z dos arquivos e criar os diretórios sem o sufixo .7z .

Como:

for archive in *.7z; do 7z x -o"'basename \"$archive\" .7z'" "$archive"; done
    
por 12.11.2015 / 16:07
1
for file in *.7z; do
    directory=${file/%.7z/}
    if mkdir ${directory}; then
        ( cd ${directory}; 7z x ../${file} )
    else
        echo "Unable to create directory ${directory} for archive ${file}" 1>&2
    fi
done

A maneira como isso funciona é a primeira iteração em todos os arquivos *.7z usando a variável file . Uma vez que ele pega um nome de arquivo, ele usa manipulação de string bash para retirar o .7z do final, e fazer uma nova variável, directory , fora disso.

Ele então tentará criar o diretório e, se puder, abrirá um subshell, entrará nesse diretório e extrairá o arquivo 7zip.

Se não foi possível criar esse diretório, uma mensagem será enviada para o erro padrão.

Eu uso um subshell para não ter que me preocupar em perder o controle de onde estou com as alterações no diretório de trabalho.

A parte mais obscura disso é essa linha:

diretório = $ {file /%. 7z /}

Esta é a manipulação de string bash mencionada anteriormente, que procurará .7z no final de uma string e, se presente, substitua-a por nada. Se eu quisesse substituí-lo por, digamos, .zip , eu poderia usar ${file/%.7z/.zip} .

    
por 12.11.2015 / 19:26