【问题标题】:Insert delimiter between digits in linux在linux中的数字之间插入分隔符
【发布时间】:2016-09-11 20:22:53
【问题描述】:

我从数据库中检索到的随机数很少。例如。

12203770
6458251
6458250
10336719
10366878
10366877
10366874
81048

现在,我必须在它们之间放置分隔符“/”。我正在使用这个命令:

[root@abc01 ~]#  awk 'BEGIN{FS="";OFS="/"} {print $1,$2,$3,$4,$5}' /tmp/abc.txt

如果数字是 8 位数字,这可以正常工作,但我的 requirement 是: 命令/脚本应从右侧保留最后 3 位数字,其余的将打印带分隔符的数字。

所需的输出:

1/2/2/0/3
6/4/5/8
6/4/5/8
1/0/3/3/6
1/0/3/6/6
1/0/3/6/6
1/0/3/6/6
8/1

请帮助。

【问题讨论】:

  • 您能解释一下为什么6458251 (6/4/5/8) 的预期输出与6458250 (6/4/5/8/) 的预期输出不同吗?
  • sed -e 's|\(.\)|\1/|g;s|\(.*\)/\(.\/\)\{3\}|\1|g' /tmp/abc.txt
  • @Simon 道歉,这是一个错字。我将编辑更改。
  • What have you tried so far?edit 您的问题显示您遇到问题的代码的minimal reproducible example,然后我们可以尝试帮助解决具体问题。您还应该阅读How to Ask
  • 虽然,答案很有帮助,但如果我输入的数字小于 3,这些都不起作用。比如说:123,234 等等。如果数字小于 3,那么代码应该只打印“/”。

标签: linux shell awk


【解决方案1】:
$ awk '{gsub(/./,"&/"); sub(/.{7}$/,"")} 1' file
1/2/2/0/3
6/4/5/8
6/4/5/8
1/0/3/3/6
1/0/3/6/6
1/0/3/6/6
1/0/3/6/6
8/1

$ sed 's#.#&/#g; s#.\{7\}$##' file
1/2/2/0/3
6/4/5/8
6/4/5/8
1/0/3/3/6
1/0/3/6/6
1/0/3/6/6
1/0/3/6/6
8/1

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。
  • @TobySpeight 你为什么要在这个极其简单、100% 可移植的答案下使用绝对基本的替换(它没有比s/old/new 简单得多!)而不是使用其他答案神秘的、不便携的、不明显的花招?如果有人不理解这个答案,那么快速浏览一下谷歌或手册页就会解释它,研究它的人会比我解释 s/old/new 的含义但如果有人曾经使用过 sed 或 awk 学到更多对于任何事情,他们都会一眼就理解这些脚本。
  • @EdMorton 虽然答案很有帮助,但如果我输入的数字小于 3,这些都不起作用。比如说:123,234 等等。如果数字小于 3,那么代码应该只打印“/”。
  • @sumitgupta 这就是为什么努力提出涵盖您的用例的示例输入很重要的原因,这样您就不会浪费人们的时间来提出和测试符合您要求的答案说您希望在针对我们期望的真正具有代表性的样本数据运行时,您提供给我们进行测试,但不要针对您的真实数据,因为您没有用您的样本输入/输出代表您的真实数据。我们怎么可能猜测您的真实数据可能有 3 位或更少的数字,或者更重要的是,在这种情况下输出应该是什么?祝你好运!
  • @EdMorton 点已被占用。下次我会记住所有这些提示。
【解决方案2】:
awk 'BEGIN{FS="";OFS="/"}{NF-=3;print}' file
1/2/2/0/3
6/4/5/8
6/4/5/8
1/0/3/3/6
1/0/3/6/6
1/0/3/6/6
1/0/3/6/6
8/1

【讨论】:

  • 您应该提到,这仅适用于某些 awk(例如 gawk),因为 1)设置 FS="" 导致输入被拆分为字符,以及 2)递减 NF 导致字段被删除.两者都不是 POSIX。
  • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。