Para proteger contra a exclusão de subdiretórios vazios, o IMO, a maneira mais simples é mover para um diretório temporário e, em seguida, renomear o diretório temporário para o diretório antigo. Digamos que o diretório em questão seja foo
e você queira que foo/*/*
se torne foo/*
. Faça algo como:
tar c --remove-files foo | tar xv --strip-components=2 --backup=t --one-top-level=temp
mv temp foo
- Com
--remove-files
, o primeiro tar
excluirá os arquivos conforme eles são processados e, finalmente, excluirá foo
.
- Com
--strip-components=2
, o segundo tar
cortará o foo/*/
dos caminhos que está sendo extraído, portanto, foo/a/b
se tornará b
.
-
--backup=t
é o mesmo que com cp
ou mv
- crie cópias de backup numeradas. No entanto, mv
faz cópias de diretórios se eles tiverem o mesmo nome, mas tar
mesclará os diretórios e fará backups de arquivos.
-
--one-top-level=temp
diz a tar
para criar um diretório chamado temp
e extrair arquivos para lá.
Por exemplo:
$ tree bar
bar
├── a
│ ├── c
│ │ └── bar
│ ├── d
│ │ └── bar
│ ├── e
│ │ └── bar
│ └── f
│ └── bar
├── b
│ ├── c
│ │ └── bar
│ ├── d
│ │ └── bar
│ ├── e
│ │ └── bar
│ └── f
│ └── bar
└── c
├── c
│ └── bar
├── d
│ └── bar
├── e
│ └── bar
└── f
└── bar
E depois de executar os comandos tar
:
$ tar c --remove-files bar | tar xv --strip-components=2 --backup=t --one-top-level=temp
bar/a/e/
bar/a/e/bar
bar/a/f/
bar/a/f/bar
bar/a/c/
bar/a/c/bar
bar/a/d/
bar/a/d/bar
bar/b/e/
bar/b/e/bar
Renaming ‘temp/e/bar’ to ‘temp/e/bar.~1~’
bar/b/f/
bar/b/f/bar
Renaming ‘temp/f/bar’ to ‘temp/f/bar.~1~’
bar/b/c/
bar/b/c/bar
Renaming ‘temp/c/bar’ to ‘temp/c/bar.~1~’
bar/b/d/
bar/b/d/bar
Renaming ‘temp/d/bar’ to ‘temp/d/bar.~1~’
bar/c/e/
bar/c/e/bar
Renaming ‘temp/e/bar’ to ‘temp/e/bar.~2~’
bar/c/f/
bar/c/f/bar
Renaming ‘temp/f/bar’ to ‘temp/f/bar.~2~’
bar/c/c/
bar/c/c/bar
Renaming ‘temp/c/bar’ to ‘temp/c/bar.~2~’
bar/c/d/
bar/c/d/bar
Renaming ‘temp/d/bar’ to ‘temp/d/bar.~2~’
$ tree temp
temp
├── c
│ ├── bar
│ ├── bar.~1~
│ └── bar.~2~
├── d
│ ├── bar
│ ├── bar.~1~
│ └── bar.~2~
├── e
│ ├── bar
│ ├── bar.~1~
│ └── bar.~2~
└── f
├── bar
├── bar.~1~
└── bar.~2~
4 directories, 12 files
Com a saída tar
, é possível ver quando tar
renomeou os arquivos para backup, permitindo que você acompanhe quais arquivos se tornaram quais backups.
Estou um pouco surpreso pelo fato de funcionar, mas você pode realmente fornecer o mesmo nome de diretório para --one-top-level
e eliminar a necessidade de renomear. Apenas este pipeline é suficiente:
tar c --remove-files bar | tar xv --strip-components=2 --backup=t --one-top-level=bar