Remova um ou mais campos, delimitados por um "-", no final da linha

8

Vou analisar os dados googleapis.txt

bucket,abc-def-ghi-45gjd4-wwxis
bucket,dde-wwq-ooi-66ciow-po22q
instance,jkl-mno-1-zzz-68dkakw-oo9w8
disk,pqr-stu-10-kuy-l2oxapw-rp4lt

Espero o resultado como este abaixo

bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

Eu estou pensando que eu tenho que mudar -para ser um espaço e, em seguida, execute este comando

cat googleapis.txt | awk '{$NF="";sub(/[ \t]+$/,"")}1' | awk '{$NF="";sub(/[ \t]+$/,"")}1'

Entendi isso https://stackoverflow.com/a/27794421/8162936 Depois de analisado, alterarei o espaço para ser um hífen de -volta.

Alguém conhece a melhor prática ou o comando shell de uma linha para analisá-lo? Obrigado a todos

Nicky Puff
fonte

Respostas:

10

com sedvocê pode fazer:

sed -E 's/(-[^-]*){2}$//' infile

combine um padrão -anythingduas vezes a (...){2}partir do final $de cada linha e remova-o.

αғsнιη
fonte
7
$ sed 's/-[[:alnum:]]*-[[:alnum:]]*$//' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

Isso usa sedpara corresponder às duas últimas substrings delimitadas por traços em cada linha e removê-las. [[:alnum:]]corresponderá a qualquer caractere alfanumérico.

Você pode reduzi-lo para

sed 's/\(-[[:alnum:]]*\)\{2\}$//' file

ou seja, combine e exclua dois conjuntos de -[[:alnum:]]*at ao final de cada linha.

Com o GNU awk, você também pode fazer

$ awk -F '-' 'BEGIN { OFS=FS } { NF -= 2; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

mas mudar NFdessa forma não é portátil e deve ser evitado (não há garantia de que ele mude o registro atual). Não funcionaria com o BSD awk, por exemplo.

Com o padrão awk, sem recorrer ao uso sub()(o que seria apenas para imitar sed), você teria que recriar o registro atual dos campos que deseja usar (no nosso caso, todos, exceto os dois últimos campos delimitados por traços):

$ awk -F '-' 'BEGIN { OFS=FS } { nf = split($0,a) - 2; $0=""; for (i=1; i<=nf; ++i) $i = a[i]; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Kusalananda
fonte
4

Com reve cut:

rev file | cut -d'-' -f3- | rev

Inverta as linhas, cutcampo 3 até o final da linha e inverta o texto novamente.


Com grep(e PCRE):

grep -Po '.*(?=(-[^-]*){2}$)' file
  • -Puse expressões regulares compatíveis com perl com uma aparência positiva (?...)contendo duas correspondências -seguidas por quaisquer -caracteres que não sejam caracteres
  • -o imprimir apenas peças correspondentes
Freddy
fonte
4
$ perl -F- -lane 'print join "-", @F[0..($#F-2)]' googleapis.txt
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy

Isso divide automaticamente cada linha de entrada na matriz @F, usando o delimitador -.

Em seguida, ele imprime uma fatia da matriz, com exceção dos dois últimos campos, reunida novamente com -caracteres.

cas
fonte
1

você pode fazer isso de várias maneiras, como mostrado aqui:

$ perl -F- -pale '$"="-";$#F-=2;$_="@F"' file

Divida as linhas em um traço, defina o marceneiro do elemento da matriz como traço, corte os dois últimos elementos e defina a linha atual para a matriz unida com traços.

$ awk -F- '{
   t = $1
   for ( i=2; i<NF-1; i++ ) t = t FS $i
   $0 = t
}1' file

Isso ocorre com o processamento de sequência simples:

$ perl -lne 'print substr($_, 0, rindex($_,"-",-1+rindex($_,"-")))' file

.

$ sed -ne '
   y/-/\n/
   :a;h;s/\n/-/;/\n.*\n/ba
   g;P
' file

Resultados:

bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Rakesh Sharma
fonte