Por meio da página de manual do unzip:
-j junk paths. The archive's directory structure is not recreated;
all files are deposited in the extraction directory (by default,
the current one).
Então:
unzip -d D -j f.zip */D/*
Extraia tudo para uma pasta chamada D, mas sem estrutura de diretório (observe que isso extrairá arquivos nos subdiretórios de D para a pasta D de nível superior).
OEDIT OP queria manter a estrutura do arquivo sob a pasta D.
unzip -l f.zip | grep 'A/B/C/D' | \
perl -ple 's/\s+\d+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/$1/' | \
while read file
do
unzip -j -d "$(echo $file | sed 's:A/B/C/\(.*\)/.*::g')" f.zip "$file"
done
Cada passo em partes:
unzip -l f.zip
obtenha uma lista de arquivos em f.zip
grep 'A/B/C/D'
mostre as linhas que mostram arquivos no diretório de destino
perl -ple 's/\s+\d+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/$1/'
use o perl para obter o nome do arquivo naquela linha correspondente (meu sed-fu não é tão bom quanto o de Stephane, então usarei o perl!), NOTE que isso lida com espaços em nomes de arquivos : )
while read file
do
percorra os arquivos produzidos a partir dos comandos acima e atribua-o a $file
unzip -j -d "$(echo $file | sed 's:A/B/C/\(.*\)/.*::g')" f.zip "$file"
descompacte o destino $file
, refazendo seu caminho, no diretório de destino obtido de
echo $file | sed 's:A/B/C/\(.*\)/.*::g'
que remove o caminho A / B / C / inicial do nome do arquivo, observe que ele é empacotado em $ () (a Command substitution
, consulte bash para obter mais detalhes) e que a substituição de comandos está entre aspas duplas para preservar espaços (e realmente avaliar o $()
).
done
conclui o loop.
Isso, na verdade, executa uma operação de descompactação para cada arquivo correspondente em A / B / C:
unzip -j -d "D" f.zip "A/B/C/D/"
unzip -j -d "D" f.zip "A/B/C/D/b"
unzip -j -d "D" f.zip "A/B/C/D/e"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/b"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/e"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/d"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/c"
unzip -j -d "D/stupid space" f.zip "A/B/C/D/stupid space/a"
unzip -j -d "D" f.zip "A/B/C/D/d"
unzip -j -d "D" f.zip "A/B/C/D/f"
Se você executar esse comando para extrair uma estrutura de arquivos já existente, precisará adicionar mais -o
a override
arquivos existentes (ou a primeira operação de descompactação que bloqueará um arquivo será solicitada com replace D/b? [y]es, [n]o, [A]ll, [N]one, [r]ename: extracting: D/b
e então bombardeie para fora). Se você precisar desse aviso, terá que usar outro método de looping que não use read e também lida com espaços ( for $( ... )
falhará no teste). Vou deixar isso como um exercício para você se exercitar se precisar fazer isso!