Sed para alterar uma data de nascimento usando uma expressão regular

1

Estou interessado em alterar uma data de nascimento em um arquivo de texto para uma data diferente de 14/11/46. Eu quero fazer isso sem ter que saber a data de nascimento anterior e, em vez disso, ser capaz de pesquisar genericamente. Eu sei o nome da pessoa que a data de nascimento está associada, então eu posso usar isso para fazer a substituição

Eu tentei isso:

sed "s/^PersonsName\/[1-12]\/[0-31]\/[0-99]/11\/14\/46/g" txt.file

Mas não funciona e não sei como proceder

As respostas sugeridas abaixo não funcionaram para mim. Vou dar alguns dados de exemplo e ver se isso ajuda a esclarecer.

Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350

Vamos fingir que estou tentando mudar a data de nascimento do Popeye (que está no final), mas quero pesquisar sem precisar conhecer a atual. Eu sei que usar uma expressão regular é fundamental aqui, mas até agora os exemplos que vi não funcionaram. Talvez fornecer os dados de exemplo acima ajudará

[Saída esperada]

Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:11/14/46:22350

Tudo o que estou interessado em mudar é a data de nascimento no final de 11/14/46

    
por Justin 18.10.2014 / 01:54

3 respostas

0

Você pode usar o comando abaixo sed

$ sed '/^Popeye Sailor:/s/:[^:]*\(:[^:\/]*\)$/:11\/14\/46/' file
Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:11/14/46:22350

Altera a data apenas nas linhas que começam com Popeye Sailor:

    
por Avinash Raj 18.10.2014 / 20:12
0

[1-12]\/[0-31] e [0-99] não significam 1 a 12, 0 a 31 e 0 a 99.

  • [1-12] significa um intervalo de caracteres a partir de 1 até 1 e um 2. Em essência: [12] . (Compare com [0-1a] .)
  • [0-31] significa um intervalo de caracteres a partir de 0 até 3 e um 1: [0123] .

Similarmente para [0-99] . Expressar um intervalo de números com expressões regulares não é fácil.

Se os números não usarem dois dígitos ( 01/06/33 ), você terá que fazer algo como: [0-9]{1,2} para o dia e o mês e [0-9]{2} para o ano, ou o regex rapidamente ficará pesado. Isso, obviamente, arrisca a seleção de algo como 99/99/99 .

Por exemplo:

$ sed "s/^\(muru\/\)[0-9]\{1,2\}\/[0-9]\{1,2\}\/[0-9]\{2\}/1\/14\/46/g" <<<'muru/1/4/85'
muru/11/14/46
$ sed "s/^\(muru\/\)[0-9]\{1,2\}\/[0-9]\{1,2\}\/[0-9]\{2\}/1\/14\/46/g" <<<'muru/10/4/85'
muru/11/14/46
$ sed "s/^\(muru\/\)[0-9]\{1,2\}\/[0-9]\{1,2\}\/[0-9]\{2\}/1\/14\/46/g" <<<'muru/10/28/85'
muru/11/14/46

Suponho que você queira manter o nome, por isso usei referências anteriores para me referir para ele na substituição (o ).

    
por muru 18.10.2014 / 02:05
0

As datas são complicadas , mas simplificam de forma semelhante a sua tentativa…

sed -r 's,^PersonsName1?[0-9]/[1-3]?[0-9]/[0-9]{2},11/14/46,' txt.file

Explicação

  • Use -r para expressões regulares estendidas. Isso permite (por exemplo) ? .
  • Geralmente, prefiro aspas simples ' em vez de double " , portanto não há expansão de shell.
  • Em vez de usar os delimitadores / as sed , você pode usar o que quiser. Aqui eu usei , , para que não precisemos escapar do literal / s.
  • 1?[0-9] corresponde a 1 opcional e precisa de 0 a 9, para o mês.
  • [1-3]?[0-9] match e opcional 1-3 e um necessário 0-9 para o dia.
  • [0-9]{2} corresponde a dois dígitos do ano.
  • N.B. que isso potencialmente terá algumas correspondências falsas. por exemplo. 0/0/00 e 19/39/99 corresponderão, mas você pode ajustar o regex mais se quiser. Veja o link acima para mais informações.

Mais comentários

Observe que isso corresponde a algo como PersonsName11/11/11 e substitui tudo, semelhante ao que sua tentativa tentou fazer. Se você deseja substituir apenas a data, use o seguinte em seu lugar.

sed -r 's,^(PersonsName)1?[0-9]/[1-3]?[0-9]/[0-9]{2},1/14/46,' txt.file

Aqui, capturamos PersonsName , usando parênteses. Então podemos nos referir a ele novamente na seção de substituição com .

    
por Sparhawk 18.10.2014 / 02:16