将行首的数字移动到行尾

Move numbers at the beginning of the line to the end of the line

我有一个来自 Unix uniq -c 命令的输出,它在每行的开头打印一个字符串的出现次数。该字符串表示由竖线分隔的两位作者(例如,Aabdel-Wahab S|Abdel-Hafeez EH)。

  1 Aabdel-Wahab S|Abdel-Hafeez EH
  1 Aabdel-Wahab S|Abdulla AM
  4 Aabdel-Wahab S|Ahmad AK
  1 Aabdel-Wahab S|Mosalem FA
  1 Aabye MG|Andersen AB
  8 Aabye MG|Changalucha J
  1 Aabye MG|Christensen DL
  1 Aabye MG|Faurholt-Jepsen D

我需要 grep 出现次数并将其移动到行尾。例如:

Aabdel-Wahab S|Abdel-Hafeez EH|1
Aabdel-Wahab S|Abdulla AM|1
Aabdel-Wahab S|Ahmad AK|4
Aabdel-Wahab S|Mosalem FA|1
Aabye MG|Andersen AB|1
Aabye MG|Changalucha J|8
Aabye MG|Christensen DL|1
Aabye MG|Faurholt-Jepsen D|1

请注意,频率现在用竖线分隔。下面粘贴的是我在 Awk 中的一行代码:

awk '{num=;=""; sub(/^ /,""); print [=12=],"|",num;}' file

但是 Awk 在最终管道周围添加了额外的空间:

Aabdel-Wahab S|Abdel-Hafeez EH | 1
Aabdel-Wahab S|Abdulla AM | 1
Aabdel-Wahab S|Ahmad AK | 4
Aabdel-Wahab S|Mosalem FA | 1
Aabye MG|Andersen AB | 1
Aabye MG|Changalucha J | 8
Aabye MG|Christensen DL | 1
Aabye MG|Faurholt-Jepsen D | 1

知道如何进行(不需要使用 Awk)吗?

您可以使用 printf:

awk '{num=;=""; sub(/^ /,""); printf("%s|%s\n",[=10=],num);}' file

使用sed

sed -r 's/\s*([0-9]+)\s*(.*)/|/' infile
  • \s* 匹配零个或多个空格。
  • ([0-9]+) 匹配用于组匹配的一个或多个数字和括号。
  • (.*) 也匹配用于组匹配的任何内容和括号。
  • | 中,我们正在打印第二组匹配,即 (.*),下一个第一组匹配,即 ([0-9]+),中间有竖线。

POSIXly,你会这样做:

sed 's/^ *\([0-9][0-9]*\) *\(.*\)$/|/' infile

这是使用 sed 而不是 awk 的真实情况:

sed 's/^  *\([0-9][0-9]*\) *\(.*\)/|/' file

正则表达式细分:

  • ^ * 从至少一个开始 space
  • \( 开始捕获第一组
    • [0-9][0-9]* 至少匹配一位数字
  • \) CG一结束
  • * 任意数量的 space 个字符
  • \(.*\) 捕获输入行的其余部分(CG 二)

替换字符串更改捕获组的顺序,中间有一个 |

Awk 本身不添加空格,您告诉 awk 添加空格。您认为 ,print 1,2 中意味着什么(提示:在 awk 手册页中查找 OFS)?只是不要那样做:

awk '{num=; =""; sub(/^ /,""); print [=10=] "|" num}' file