regex: corresponde a dois / de volta do fim de linha [duplicado]

1

Eu tenho um arquivo de caminhos de arquivos. A profundidade dos diretórios é de vários comprimentos e nomes de caminho. Eu gostaria de combinar dois diretórios para trás (dois / s) e excluir a correspondência, criando um novo arquivo com os resultados.

por exemplo:

/dir1/dir2/dir3/dir4/dir5/dir6/dir7/output_job3344.xml
/dir1/dir2/dir3/dir4/dir5/otherfile.txt

o resultado seria:

/dir1/dir2/dir3/dir4/dir5/dir6/
/dir1/dir2/dir3/dir4/

Eu tentei algo assim:

awk -F'/*./.*$' '{print $0}' deep.list

mas isso não deu certo.

    
por Greg-905 21.08.2018 / 23:20

1 resposta

0

Sua ideia é inteligente , mas precisa de algumas correções. Veja como você provavelmente quis dizer isso:

awk -F'[^/]*/[^/]*$' '{print $1}' deep.list

Explicação:

Em primeiro lugar, você provavelmente escreveu incorretamente .* as *. .

Então, o modificador * é ganancioso , portanto, você precisa tomar cuidado para não corresponder a mais do que pretendia! A solução é simples, embora um pouco menos legível: use [^/]* em vez de .* . Dessa forma, você combina todos os caracteres, exceto / .

Por fim, $0 representa a linha inteira, que não foi alterada nem um pouco, especificando um separador de campo personalizado especialmente criado. Nesse caso, você deseja imprimir o primeiro campo: $1 .

Aqui está uma abordagem diferente das duas respostas ligadas por @ ender.qa :

awk '{gsub("[^/]+/[^/]+$","");print}' deep.list

E um empregando um loop:

awk -F/ '{for(i=1;i<=NF-2;i++){printf "%s/",$i}; print ""}' deep.list

O método de substituição é mais facilmente implementado em Perl:

perl -lape 's"[^/]+/[^/]+$""' deep.list

ou sed:

sed -E 's"[^/]+/[^/]+$""' deep.list
    
por 04.09.2018 / 09:06

Tags