Como remover o primeiro dois pontos ':' de um registro de data e hora?


10

Eu sou novo em programação !!

Alguém pode ajudar a remover :a primeira posição em um carimbo de data / hora::29.06.2019 23:03:17

Atualmente, estou tentando fazer isso usando os comandos awk / cut, como mostrado abaixo:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2)"
echo "$TDS"


29.06.2019 23

E a saída não é o que eu queria! Quero imprimi-lo como 29.06.2019 23:03:17.

Respostas:


14

Para cortar o primeiro caractere, você também pode usar cut -c:

$ echo ":29.06.2019 23:03:17" | cut -c 2-
29.06.2019 23:03:17

11

Usar

cut -d: -f2-

ao invés de

cut -d: -f2

para obter qualquer coisa do segundo campo até o final da linha:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2-)"
echo "$TDS"

8

awké uma ferramenta interessante e você pode resolver tarefas muito complexas com ela. Mas, para sua pergunta, prefiro me ater aos recursos básicos do bash.

Para essa remoção fácil da subestação, eu faria o seguinte:

zehe="Logfile started :29.06.2019 23:03:17"
echo "${zehe#*:}"

isto imprimirá:

29.06.2019 23:03:17

Quando eu estava na sua posição e comecei a aprender programação e bash, aprendi muito deste manual:

ABS - Guia Avançado de Bash-Scripting

Mais alguns exemplos e informações interessantes para o seu problema podem ser encontrados aqui , procure por 'Remoção de Substring'.


3
+1 Isso! Como a pergunta está marcada como "bash", deve-se considerar a preferência das grandes (embora muitas vezes obscuras) capacidades do bash de manipular seqüências de caracteres que são muito mais rápidas do que carregar ferramentas externas.
Rexkogitans 17/07/19

2
@rexkogitans Como já estamos chamando grep ou awk para analisar um arquivo, o bash não será mais rápido. De fato, sempre que você precisar analisar um arquivo bash será lento. Todas as conchas são lentas e o bash é mais lento que a maioria. Dito isto, os recursos de manipulação de strings do shell geralmente são a melhor abordagem, mas somente se você já tiver a entrada como variável.
terdon 17/07/19

8

Aqui está uma sedsolução:

$ echo ':29.06.2019 23:03:17' | sed 's/^://'
29.06.2019 23:03:17

O que o comando sed 's/^://'está fazendo é substituir so caractere de dois pontos :do início ^de cada linha pela string vazia //.

Aqui está uma awksolução complicada , na qual alteramos o separador de campos para ^:, descrito acima, e produzimos o segundo campo (de cada linha):

$ echo ':29.06.2019 23:03:17' | awk -F'^:' '{print $2}'
29.06.2019 23:03:17

A tarefa poderia ser realizada também com grep( explicação ), provavelmente esta poderia ser a solução mais rápida para grande quantidade de dados:

$ echo 'Logfile started :29.06.2019 23:03:17' | grep -Po '^Logfile started :\K.*'
29.06.2019 23:03:17

Ou processe o arquivo diretamente pelo seguinte comando, onde a limitação ^é removida:

grep -Po 'Logfile started :\K.*' process.log

O acima pode ser alcançado também por sedgrupos de captura e ()->\1:

sed -nr 's/^.*Logfile started :(.*)$/\1/p' process.log

Onde a expressão ^.*<something>.*$corresponderá à linha inteira, que contém <something>. O comando s/old/new/substituirá essa linha pelo conteúdo do primeiro grupo de captura (a expressão entre colchetes pode ser mais concreta). A opção -rativa as expressões regulares estendidas. A opção -nsuprimirá a saída normal de sede, finalmente, o comando pimprimirá as correspondências.


Eu nunca soube que awkpoderia ter um FS multi-personagem com personagens com significado especial! Coisa que aprendi hoje.
Floris

6

Como você já está processando isso awk, você também pode fazer a coisa toda diretamente:

$ echo "foo bar :29.06.2019 23:03:17" |  awk '{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

O subformato geral do comando é sub(/REGEX/, REPLACEMENT, TARGET)e substituirá todas as correspondências da expressão regular REGEXpela sequência REPLACEMENTna sequência de entrada TARGET. Aqui, estamos substituindo o primeiro :( ^significa "o começo") do terceiro campo ( $3) por nada.

Obviamente, se você estiver fazendo isso no awk, poderá fazer tudo no awk e fazer tudo em uma única operação:

$ echo "Logfile started :29.06.2019 23:03:17" | 
    awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Ou, no seu caso:

TDS="$(awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' process.log)"
echo "$TDS"

0

Outra solução do bash:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Isso usa o pipeline em vez da atribuição de variável intermediária.
  • O comando xargsconverte stdin(entrada padrão) em parâmetros posicionais para o bashcomando.
  • Substitua echopor tail -n1 /path/to/reportfile.txt.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.