使用 sed 替换冒号左侧出现的所有破折号

使用 sed 替换冒号左侧出现的所有破折号

我在文件中有以下值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

我需要将冒号 (:) 左侧出现的所有破折号 (-) 替换为下划线 (_)。

我已经尝试过,sed '/.*: /s/-/_/g' config.yml但它替换了所有破折号(包括config/project-scratch-def.json)。

我试过了sed '/^[^:]*:/s/-/_/g' config.yml,希望能停在冒号处,但效果是一样的。

答案1

$ 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

awk脚本将文件读取为一:组用 - 分隔的字段。它适用gsub()于每行的第一个字段,将每个破折号更改为下划线。单独的1缩写{ print }将打印每个(现已修改的)输入行。

FS=':' OFS=':'将输入和输出字段分隔符设置为:

也可以sed通过一些非常复杂的正则表达式或利用其保留空间(或两者)来做到这一点,但这不是一个“脱口而出”的解决方案。


(经过一番思考)使用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

每一步说明:

  1. h:将模式空间(当前输入行)复制到保持空间(“通用”缓冲区)。
  2. s/^[^:]*//::删除模式空间中第一个之前的所有内容。
  3. x:交换保持空间和模式空间。
  4. s/:.*$//:删除:模式空间中的 及其后面的所有内容。

    模式空间现在包含 未修改的左侧:,而保持空间包含未修改的右侧,包括:.

  5. y/-/_/:将模式空间中的所有破折号更改为下划线。

  6. G:将保留空间附加到模式空间的末尾,并在两者之间使用换行符。
  7. s/\n//:删除上一步中的换行符。
  8. (隐式p):将模式空间打印到标准输出。

步骤 4 和步骤 5 可以互换,结果不会有任何变化。

简而言之:sed不是(可能不是)适合这项工作的工具。

答案2

思考sed您可以通过替换循环中的破折号来完成此操作,一旦第一个冒号之前的所有内容都不包含破折号,就中断:

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

前任。

$ 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

答案3

我通过3步取得了结果

首先,我在保存在 Second_part.txt 文件中的冒号之后分隔了第二部分

第二步我将第一部分分开直到冒号并将“-”替换为“_”并保存在文件first_part_after_relacement中

使用粘贴命令的最后一步我加入了两个文件,从而达到了所需的结果

命令

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

输出

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

注意:与之前提供的解决方案相比,多了 2 个步骤

相关内容