pt - removendo zero - / 08 / para / 8 /

5

Qual comando sed eu preciso usar para transformar / 08 / em / 8 /?

Eu estou olhando para me livrar de todos os excessos 0 na saída do meu comando.

Eu consegui reduzir para um 0 extra.

sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp

Outputs: at 12:27 AM on 5/[1-9]

sed -ie 's/\/0?\//\/?\//g' ~/tmp

Outputs: at 12:27 AM on 5/08

Script completo:

#!/bin/bash

echo $@ > ~/tmp
sed -ie 's/\/0[1-9]\//\/[1-9]\//g' ~/tmp
AA='awk '{print $2}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//''
BB='awk '{print $3}' ~/tmp'
CC='awk '{print $1}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//''
DD='awk '{print $5}' ~/tmp | awk -F : '{print $1":"$2}' | sed 's/^0*//''
EE='awk '{print $6}' ~/tmp'
FF='awk '{print $4}' ~/tmp | awk -F / '{print $1"/"$2}' | sed 's/^0*//''

if [ $# = 3 ]; then
    echo "at $AA $BB on $CC"

elif [ $# = 6 ] && [ $CC = $FF ]; then
    echo "from $AA $BB to $DD $EE on $FF"

elif [ $# = 6 ]; then
    echo "from $AA $BB on $CC to $DD $EE on $FF"
fi
rm ~/tmp

Exemplo de saída de entrada (alias = dt):

With current sed command

dt 05/08/2017 02:27:25 AM

at 2:27 AM on 5/[1-9]

Without first sed command

dt 05/08/2017 02:27:25 AM

at 2:27 AM on 5/08

Solved -- third line replaced with sed -rie 's/\/0(.?)/\//g' ~/tmp

dt 05/08/2017 01:03:56 AM

Outputs: at 1:03 AM on 5/8

    
por Joshua C. 08.05.2017 / 08:03

4 respostas

6

NOTA : esta é uma resposta editada para tornar a solução o mais geral possível. Veja o histórico de edições para ver o que foi feito originalmente e veja os comentários dos problemas com a resposta anterior.

A chave aqui é usar o agrupamento via () e -r para expressões regulares estendidas. O agrupamento de padrões com () permitirá que você se refira a eles com base em sua posição na notação via \NUMBER . Em particular, aqui está o que eu criei:

sed -r 's/0*([^0]+)\/0*([^0]+)/\//g' 

Isso é assim:

  • corresponde a zero ou mais caracteres que são zero
  • agrupa um ou mais caracteres diferentes de zero que seguem
  • em seguida, procure por barra seguida de zero ou mais caracteres que são zero
  • e agrupar um ou mais caracteres diferentes de zero que seguem

Na prática, isso funciona assim com um número variável de zeros:

$ echo "at 12:27 AM on 11/08/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\//g'                                                                         
at 12:27 AM on 11/8/2017
$ echo "at 12:27 AM on 00000011/000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\//g'                                                           
at 12:27 AM on 11/8/00002017
$ echo "at 12:27 AM on 011/08/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\//g'                                                                    
at 12:27 AM on 11/8/00002017
$ echo "at 12:27 AM on 000000011/0000008/00002017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\//g'                                                         
at 12:27 AM on 11/8/00002017

Observe que isso é bom o suficiente para reter o que vier na parte do ano, se necessário. Se quisermos nos livrar disso também, também podemos adicionar um terceiro grupo.

$ echo "at 12:27 AM on 005/0025/0002017" | sed -r 's/0*([^0]+)\/0*([^0]+)\/0*([^0]+)/\/\//g'                                                    
at 12:27 AM on 5/25/2017

Isso também funciona muito bem com outros caracteres (o que não era obrigatório, mas é bom ter):

$ echo "at 12:27 AM on 0November/00Fifth/2017" | sed -r 's/0*([^0]+)\/0*([^0]+)/\//g'                                                             
at 12:27 AM on November/Fifth/2017
    
por 08.05.2017 / 08:26
3
sed -e 's/\<00*\([1-9]\)//g' input_data

Trabalhando: Esta regex procura por um inteiro [0-9] em cuja esquerda esteja uma string de 0s e esses zeros são limitados por uma quebra de palavra \< .

    
por 08.05.2017 / 08:26
3
sed -ie 's/\/0?\//\/?\//g' ~/tmp

Primeiro, você pode usar outros caracteres além da barra como separadores para s/// , que permitirão que você use as barras sem escapes. Segundo, as anotações de @ Stéphane , com -ie o e serão tiradas como uma extensão para o arquivo de backup, para obter um arquivo de backup chamado tmpe . Eu alteraria a extensão (ou a removeria) e regravaria da seguinte forma:

sed -i.bak -e 's,/0?/,/?/,g' ~/tmp

Agora, é mais fácil ver o padrão real correspondente: as strings // e /0/ , a string literal /0?/ , que é substituída por /?/ . (No ERE, o ? corresponderia a zero ou a uma cópia do grupo anterior, então zero ou um 0 ).

O ponto de interrogação não é especial na substituição, por isso aparecerá literalmente. Como afirmado em outras respostas, você precisa usar o agrupamento ( (...) com EREs ou \(...\) com BREs) para capturar partes do padrão e, em seguida, na substituição para colocá-las de volta.

Então, algo assim:

sed -i.bak -Ee 's,/0*([1-9]),/,g' ~/tmp

Embora note que ainda será necessária a barra na frente, o primeiro zero em 05/08/2017 não será substituído.

O uso de \< do Rakesh é provavelmente a jogada inteligente aqui, se você quiser remover zeros à esquerda de todas as palavras. Então, novamente, alterar 12:03:04 para 12:3:4 pode não ser o que você deseja.

Esse último exemplo de alteração de 05/08/2017 01:03:56 AM para at 1:03 AM on 5/8 poderia ser feito com um comando sed :

$ echo '05/08/2017 01:03:56 AM' | 
  sed -Ee 's,0*([0-9]+)/0*([0-9]+)/[0-9]+ 0*([0-9]+):([0-9]+):[0-9]+ ([AP]M),at :  on /,'
at 1:03 AM on 5/8

Eu não olhei para quais outros formatos de entrada você queria aceitar.

    
por 08.05.2017 / 10:26
0

Você não pode usar uma expressão regular no texto de substituição. Você quer dizer

sed 's/0\([0-9]\)//'
    
por 08.05.2017 / 08:20