Podemos usar sed
ou awk
resolver completamente o problema.
Com sed
:
$ sed 's/^.\./0&/' file.txt
Quando &
ocorrer na parte de substituição do comando de substituição ( s
), ela será expandida para a parte da linha de entrada que corresponde à parte padrão do comando.
A expressão regular ^.\.
significa " corresponder a todas as linhas que começam com ( ^
) um caractere arbitrário ( .
) seguido por um ponto literal ( \.
) ".
Se a linha for 1.02.2017 23:40:00
, o padrão corresponderá e 1.
será substituído por 01.
no início da linha.
Com awk
:
Com base no awk
código parcial na pergunta ...
Isso, como indicado, imprimirá o segundo caractere de cada linha de entrada:
$ awk '{ print substr($0, 2, 1) }' file.txt
Podemos usar o fato de substr($0, 2, 1)
retornar o segundo caractere e usá-lo como condição:
$ awk 'substr($0, 2, 1) == "." { ... }' file.txt
O que entra { ... }
é o código que precede $0
, que é o conteúdo da linha atual, com um zero se a condição anterior for verdadeira:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt
Então, precisamos apenas garantir que todas as linhas sejam impressas:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt
substr($0, 2, 1) == "."
Obviamente, a condição também pode ser alterada para uma expressão regular (usamos exatamente a mesma expressão que usamos na sed
solução):
$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt
Algumas pessoas que pensam que "menor é sempre melhor" escreveriam isso como
$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt
(e provavelmente também remover a maioria dos espaços: awk '/^.\./{$0="0"$0}1' file.txt
)
sed 's/^.\./0&/' file.txt
,. Eu acho que você deveria colocar isso no início desta resposta. Ainda assim, +1.Com sed:
O padrão
/^.\./
procura qualquer caractere e um ponto literal no início da linha^
e, se isso corresponder,s
substitua o início da linha por um zero, adicionando efetivamente o zero ao início.O sed expressoin
s/.\{0\}/0/
é um tanto estranho, corresponde a zero ou mais cópias de qualquer coisa e é substituído por um zero. É claro que o padrão corresponderá em todas as posições da sequência, mas comos///
apenas substitui a primeira correspondência, ele funcionará conforme o desejado. Uma maneira singular de fazer isso, no entanto.Ou com o awk, uma regex semelhante funcionaria para corresponder à linha, mas podemos usar
substr
:Primeiro testamos se o segundo caractere é um ponto e, em seguida, adicionamos um zero à frente da linha. A final invoca a ação padrão de imprimir a linha após quaisquer modificações.
fonte
Você disse awk e sed, mas parece que você está tentando formatar uma data e, para isso, eu usaria o
date
comando Por exemplo:irá produzir
O
sed
comando no meio altera os períodos para barras para entradadate -d
. As opções de formato permitem a saída em praticamente qualquer formato desejado. O%m
em particular irá zerar o mês, que é o que parece que você está tentando fazer.Como Kusalananda aponta:
Ainda mais compacto (data GNU e Bash):
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
fonte
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
s|\.|/|g
. Caso contrário, como observado acima: Nice catch, +1Uma estratégia diferente da apresentada nas outras respostas: você pode usar "." como o separador de campos.
Você pode jogar isso para:
Para sed, há um comando mais curto, apresentado em outra (ótima) resposta.
fonte
awk -F. '{print ($1<10?0$0:$0)}' file
Com sed poderia ser
Isso será usado
^
para ancorar no início da linha e, em seguida, capturar qualquer caractere único em um grupo, seguido por um literal.
e depois qualquer outra coisa. Se combinarmos que imprimimos a0
, nosso primeiro grupo de capturas (o caractere no início da linha) e, em seguida.
, nosso segundo grupo de capturas (o restante da linha)fonte
&
é seu amigo. Veja o exemplo sed de Kusalananda.sed
que poderia ser útil em outras situações, não apenas este problema específico