O comando grep que localiza / exclui toda a linha em que um caractere separador aparece um certo número de vezes?

3

Existe um utilitário Unix para restringir um arquivo ou lista de diretórios a um número mínimo e máximo de níveis de profundidade?

Eu tenho um comando git que exibe uma listagem única dos diretórios onde os arquivos foram alterados, git diff --name-only HEAD~3 HEAD~0 | sed 's|/[^/]*$||' | uniq e eu quero limitar a saída ainda mais àqueles com um certo número de níveis de profundidade. Existe uma maneira de conseguir isso?

Aqui está um exemplo de uma instalação Drupal . Depois de instalar ou atualizar módulos, o comando git mostra quais módulos foram adicionados ou alterados. O diretório do módulo é o 4º nível, então qualquer diretório mais profundo deve ser cortado e duplicatas devem ser removidas do diretório de nível 4

sites/all/modules/table_trash
sites/all/modules/table_trash/css
sites/all/modules/table_trash/drush
sites/all/modules/table_trash/js
sites/all/modules/table_trash/libraries
sites/all/modules/table_trash/libraries/variants/js
sites/all/modules/table_trash
sites/all/modules/video_filter
sites/all/modules/views_aggregator
sites/all/modules/views_aggregator/views
sites/all/modules/views_aggregator
sites/all/modules/views_aggregator/views_aggregator_more_functions
sites/all/modules/views_php
sites/all/modules/views_php/plugins/views
sites/all/modules/views_php
sites/all/modules/views_watchdog
sites/all/modules/views_watchdog/views/handlers
sites/all/modules/views_watchdog/views/plugins
sites/all/modules/views_watchdog/views/theme
sites/all/modules/views_watchdog/views
sites/all/modules/views_watchdog

Parece ser um caso geral de aplicação do comando grep, que elimina todas as linhas após a enésima aparência de um caractere separador, '/' nesta instância, mas estou procurando algo que também remove duplicatas da saída, que é por isso que, neste caso, preciso passar pelo comando uniq . Neste caso, o número máximo e mínimo de níveis deve ser 4.

    
por vfclists 03.02.2015 / 18:45

2 respostas

2

Você pode usar awk para fazer isso e, no processo, eliminar a necessidade de sed e uniq . Defina limit apropriadamente

git diff --name-only HEAD~3 HEAD~0 | 
awk -vlimit=3 -F'/' -vOFS='/' -- '--NF == limit && !x[$0]++'
    
por 03.02.2015 / 19:00
1
diff --name-only HEAD~3 HEAD~0 | sed -ne 's|/||5;t' -e 's||/|4p' | sort -u

Sua linha de comando praticamente já o faz. Você pode segmentar [num] th ocorrência de um padrão com um comando sed s/// ubstitution apenas adicionando o [num] ao comando. Quando você usa t est para uma substituição bem-sucedida e não especifica um destino :l abel, o t est ramifica o script. Isso significa que tudo que você precisa fazer é t est para s///5 ou mais barras e, em seguida, p rint o que resta.

Ou, pelo menos, que lida com as linhas que excedem o seu máximo. Aparentemente, você também tem um requisito mínimo. Felizmente, isso é tão simples:

sed -ne 's|/||5;t' -e 's||/|4p'

... basta substituir a quarta ocorrência de / em uma linha própria e colocar sua p rint nos sinalizadores s/// ubstitution. Como as linhas correspondentes a / 5 ou mais vezes já foram removidas, as linhas que contêm 4 / correspondem a apenas 4.

Para os únicos, uniq não funcionará, a menos que sua entrada seja sort ed. Portanto, é melhor usar sort -u mesmo assim.

Execute nos seus dados de exemplo que o sed ... | sort pipeline imprime:

sites/all/modules/table_trash/css
sites/all/modules/table_trash/drush
sites/all/modules/table_trash/js
sites/all/modules/table_trash/libraries
sites/all/modules/views_aggregator/views
sites/all/modules/views_aggregator/views_aggregator_more_functions
sites/all/modules/views_watchdog/views
    
por 09.02.2015 / 01:18

Tags