pt sed remove última instância de um caractere via pipe?

1

Estou tentando usar as respostas de este Q / A , mas estou usando uma variável que um arquivo como entrada:

Por exemplo, a versão sed:

echo "$json" | sed -n 'x;${s/,$//;p;x}; 2,$ p'

Estou tentando o mesmo com o exemplo awk sem sucesso.

A única resposta que eu poderia começar a trabalhar com o pipe está mais abaixo na página com perl echo "$json" | perl -0777 -pi -e 's/(.*),(.*?)//s' .

Eu prefiro usar sed em vez de perl como o configurações locais para perl nem sempre são configuradas nas máquinas que eu gerencio.

Como posso modificar o comando sed para usar com um pipe?

    
por Philip Kirkbride 27.10.2017 / 16:23

3 respostas

1

Essa (brilhante resposta) que você tirou é para alterações apenas na última linha.

Se você tiver apenas uma linha, é muito mais fácil; como @I_GNU_it_all_along sugeriu substituir ,] por ] :

echo "$json" | sed 's/,]/]/'

ou, a solução geral para remover a última instância de um caractere em um arquivo com o GNU sed :

echo "$json" | sed -z 's/\(.*\),//'

O que isso faz? A opção -z diz a sed para processar o buffer inteiro de uma só vez, em vez de linha por linha, portanto, podemos simplesmente substituir a última vírgula no buffer.

Infelizmente, você pode remover facilmente a primeira vírgula ( s/,// ) ou a 42ª vírgula ( s/,//42 ), mas não a última vírgula (algo como s/,//$ não está implementado).

Assim, aproveitamos o "ganancioso" * : .* irá corresponder a tantos caracteres quanto possível, então .*, irá combinar todos os caracteres até a última vírgula. Mas queremos remover apenas a última vírgula, então cercamos todo o resto com \(\) e podemos reutilizar essa parte na substituição como .

Se você não tiver a opção -z no seu sed , precisará coletar manualmente todas as linhas no buffer:

echo "$json" | sed 'H;1h;$!d;x;s/\(.*\),//'
    
por 27.10.2017 / 17:02
0

Esse é um problema específico do JSON: se o último item da matriz for seguido por comma , , qualquer validador de JSON lançará um erro informando que ele é Expected another array element at line ... .

Tente a solução awk :

Exemplo de arquivo json input.json (inválido):

[
  {
    "name": "a"
  },
  {
    "name": "b",
    "keys": [
        1,2,3,
    ]
  },
  {
    "name": "c"
  },
]
awk -v RS= '{ gsub(/,[[:space:]]*]/, "\n]", $0) }1' input.json | jq '.'

A saída (canalizada com jq ):

[
  {
    "name": "a"
  },
  {
    "name": "b",
    "keys": [
      1,
      2,
      3
    ]
  },
  {
    "name": "c"
  }
]
    
por 27.10.2017 / 16:59
0

Por que não basta substituir a instância de ,] por ] ?

echo "$json" | sed 's/,]/]/'
    
por 27.10.2017 / 16:47

Tags