
Estou tentando adicionar 0 ao início, SE houver um "." no segundo caractere dessa linha. Não consegui combinar esses dois;
awk '{ print substr( $0, 2, 1 ) }' file.txt
mostrando o segundo personagem
sed -ie "s/.\{0\}/0/" file.txt
adicionando um zero ao início.
Deveria haver um "se o segundo caractere for um ponto".
arquivo de amostra:
1.02.2017 23:40:00
10.02.2017 23:40:00
final:
01.02.2017 23:40:00
10.02.2017 23:40:00
Responder1
Podemos usar um sed
ou awk
para resolver completamente o problema.
Com sed
:
$ sed 's/^.\./0&/' file.txt
Quando &
ocorre na parte de substituição do comando de substituição ( s
), ele será expandido para a parte da linha de entrada que corresponde à parte padrão do comando.
A expressão regular ^.\.
significa "corresponde 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 da pergunta ...
Isto irá, como afirmado, imprimir o segundo caractere de cada linha de entrada:
$ awk '{ print substr($0, 2, 1) }' file.txt
Podemos usar o fato que substr($0, 2, 1)
retorna 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 zero se a condição anterior for verdadeira:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt
Então só precisamos ter certeza de que todas as linhas foram impressas:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt
É claro que a condição substr($0, 2, 1) == "."
também pode ser transformada em 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 "mais curto é sempre melhor" escreveriam isso como
$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt
(e provavelmente também remova a maioria dos espaços awk '/^.\./{$0="0"$0}1' file.txt
:)
Responder2
Com sed:
sed -e "/^.\./s/^/0/" file.txt
O padrão /^.\./
procura qualquer caractere e um ponto literal no início da linha ^
e, se corresponder, s
substitui 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 substitui por zero. É claro que o padrão corresponderá em todas as posições da string, mas como s///
substitui apenas a primeira correspondência, ele funciona conforme pretendido. Uma maneira curiosa de fazer isso, no entanto.
Ou com o awk, um regex semelhante funcionaria para corresponder à linha, mas podemos usar substr
:
awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt
Primeiro testamos se o segundo caractere é um ponto e, em caso afirmativo, adicionamos um zero à frente da linha. O último invoca a ação padrão de imprimir a linha após qualquer modificação.
Responder3
Você disse awk e sed, mas parece que está tentando formatar uma data e para isso eu usaria o date
comando. Por exemplo:
echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d
produzirá
01.02.2017 23:40:00
O sed
comando do meio altera os pontos para barras para entrada em date -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 aponta Kusalananda:
Ainda mais compacto (data GNU e Bash):date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
Responder4
Com sed poderia ser
sed 's/^\(.\)\.\(.*\)/0\1.\2/'
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 qualquer outra coisa. Se correspondermos, imprimimos a 0
, então nosso primeiro grupo de captura (o caractere no início da linha), depois a e .
então nosso segundo grupo de captura (o resto da linha)