Substitua todas as ocorrências de traço à esquerda de dois pontos usando sed

2

Eu tenho os seguintes valores em um arquivo config.yml :

scratch-org-def: config/project-scratch-def.json
assign-permset: false
permset-name: 
run-apex-tests: true
apex-test-format: tap
delete-scratch-org: false
show-scratch-org-url: true

Eu preciso substituir todas as ocorrências de traços (-) à esquerda dos dois pontos (:) com underscores (_).

Eu tentei sed '/.*: /s/-/_/g' config.yml , mas ele substitui todos os traços (incluindo config/project-scratch-def.json ).

Eu tentei sed '/^[^:]*:/s/-/_/g' config.yml , esperando parar no cólon, mas faz o mesmo.

    
por Wade 10.02.2018 / 18:11

3 respostas

3
$ awk '{ gsub("-", "_", $1) } 1' FS=':' OFS=':' config.yml
scratch_org_def: config/project-scratch-def.json
assign_permset: false
permset_name:
run_apex_tests: true
apex_test_format: tap
delete_scratch_org: false
show_scratch_org_url: true

Este script awk lê o arquivo como um conjunto de campos : -delimited. Aplica gsub() ao primeiro campo em cada linha, alterando cada traço para um sublinhado. O único 1 é a abreviação de { print } , que imprimirá cada linha de entrada (agora modificada).

FS=':' OFS=':' define os separadores de campo de entrada e saída como : .

Também é possível fazer isso com sed , seja através de alguma expressão regular muito complicada ou utilizando seu espaço de espera (ou ambos), mas essa não é uma solução que "rola para fora da língua". / p>

(depois de pensar um pouco) Usando sed :

$ sed 'h;s/^[^:]*//;x;s/:.*$//;y/-/_/;G;s/\n//' config.yml
scratch_org_def: config/project-scratch-def.json
assign_permset: false
permset_name:
run_apex_tests: true
apex_test_format: tap
delete_scratch_org: false
show_scratch_org_url: true

Explicação de cada etapa:

  1. h : Copie o espaço padrão (a linha de entrada atual) para o espaço de espera (um buffer de "uso geral").
  2. s/^[^:]*// : remova tudo antes do primeiro : no espaço de padrão.
  3. x : Troque o espaço de espera e o espaço de padrão.
  4. s/:.*$// : remova o : e tudo depois dele no espaço padrão.

    O padrão de espaço agora contém o lado esquerdo não modificado do : , enquanto o espaço de espera contém o lado direito não modificado, incluindo o : .

  5. y/-/_/ : altere todos os traços para sublinhados no espaço padrão.

  6. G : Anexe o espaço de espera ao final do espaço de padrão com uma nova linha entre os dois.
  7. s/\n// : remova o caractere de nova linha da etapa anterior.
  8. ( p implícita): imprime o espaço padrão para a saída padrão.

Os passos 4 e 5 podem ser trocados sem qualquer alteração no resultado.

Resumindo: sed não é (pode não ser) a ferramenta certa para o trabalho.

    
por 10.02.2018 / 18:17
3

Eu acho que você pode fazê-lo em sed substituindo traços em um loop, quebrando uma vez que tudo até o primeiro cólon não contém traços:

sed ':a; /^[^-:]*:/b; s/-/_/;ta'

Ex.

$ sed ':a; /^[^-:]*:/b; s/-/_/;ta' config.xml 
scratch_org_def: config/project-scratch-def.json
assign_permset: false
permset_name: 
run_apex_tests: true
apex_test_format: tap
delete_scratch_org: false
show_scratch_org_url: true
    
por 10.02.2018 / 19:33
0

Consegui os resultados em 3 etapas

Primeiro eu separei a segunda parte após os dois pontos salvos no arquivo Second_part.txt

Segundo passos eu separei a primeira parte até o cólon e substituí "-" por "_" e salvei no arquivo first_part_after_relacement

Etapa final usando o comando paste Eu uni dois arquivos para obter o resultado necessário

Comandos

sed -ne "s/\(.*:\)\(.*\)//p" l.txt > Second_part.txt
sed -ne "s/\(.*:\)\(.*\)//p" l.txt | sed "s/-/_/g" > first_part_after_relacement
paste first_part_after_relacement Second_part.txt | sed  -r "s/\s+//g"

Saída

scratch_org_def:config/project-scratch-def.json
assign_permset:false
permset_name:
run_apex_tests:true
apex_test_format:tap
delete_scratch_org:false
show_scratch_org_url:true

Nota: 2 etapas são mais quando comparadas com a solução anterior fornecida

    
por 11.02.2018 / 09:40