Você pode usar uma combinação de awk
e xargs
para conseguir isso,
sort -r directories | awk -F/ 'cache[$3, $4, $6]++' | xargs -L1 rm -rf
directories
é apenas um arquivo que contém todos os seus diretórios, sort -r directories
pode ser facilmente substituído por um canal (por exemplo, printf "%s\n" /home/*/*/Content/*/* | sort -r
).
sort -r
coloca os diretórios para manter 'em direção ao topo' da lista (ele usa o fato de que suas datas podem ser comparadas lexicograficamente, se elas não fossem, você teria que analisá-las corretamente primeiro). Finalmente awk
faz o bookering, a primeira vez que ele vê um ( user
, environment
, product
) não imprime, todas as ocorrências a seguir são impressas. Isso gera uma lista de diretórios a serem excluídos, que depois são excluídos graças a xargs
/ rm
.
Nota: se os seus nomes de arquivos / diretórios contiverem espaços ou caracteres 'estranhos', isso não funcionará muito, então você terá que modificar o comando.
O que awk -F/ 'cache[$3, $4, $6]++'
faz? Primeiro, divide as linhas de entrada em /
. Em seguida, para cada linha de entrada, verifica se a tupla que contém o 3º, 4º e 6º valores está presente no array associativo cache
. A primeira vez que uma tupla é vista, ela não está na matriz, portanto, cache[$3, $4, $6]
retorna 0
, portanto, a linha é descartada, a ++
define cache[$3, $4, $6]
a 1
. As próximas vezes que uma tupla é vista cache[$3, $4, $6]
retorna algo > 0
, o que significa que a linha é impressa.
Aqui está um exemplo simples:
$ cat example
a,c,0
a,a,2
c,a,0
a,b,2
b,a,2
a,b,0
c,a,1
b,b,0
a,b,1
a,a,1
a,a,0
b,a,1
b,c,2
b,b,2
b,c,1
a,c,1
c,c,1
$ awk -F, 'cache[$1, $2]++' example
a,b,0
c,a,1
a,b,1
a,a,1
a,a,0
b,a,1
b,b,2
b,c,1
a,c,1
$ fgrep a,b example
a,b,2
a,b,0
a,b,1
$
Observe como a linha a,b,2
foi descartada, enquanto a,b,0
e a,b,1
não o fizeram. Usar um array associativo e o operador ++
é um padrão bastante comum em awk
, por exemplo, veja 43. Remova linhas duplicadas e não-consecutivas .