将行开头的数字移到行尾

时间:2018-04-17 10:26:48

标签: awk sed text-processing

我有一个来自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=$1;$1=""; sub(/^ /,""); print $0,"|",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)吗?

4 个答案:

答案 0 :(得分:2)

这是使用sed代替awk的真实案例:

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

正则表达式细分:

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

替换字符串会更改捕获组之间的单个|的顺序。

答案 1 :(得分:2)

不要自己添加空格,你告诉 awk添加空格。您认为,print 1,2中的含义是什么(提示:在awk手册页中查找OFS)?只是不要这样做:

awk '{num=$1; $1=""; sub(/^ /,""); print $0 "|" num}' file

答案 2 :(得分:1)

您可以使用printf

awk '{num=$1;$1=""; sub(/^ /,""); printf("%s|%s\n",$0,num);}' file

答案 3 :(得分:1)

使用sed

sed -r 's/\s*([0-9]+)\s*(.*)/\2|\1/' infile
  • \s*匹配零个或多个空格。
  • ([0-9]+)匹配用于群组匹配的一位或多位数字和括号。
  • 此处(.*)再次匹配用于群组匹配的任何内容和括号。
  • \2|\1中,我们正在打印第二组匹配,即(.*),下一个第一组匹配,即([0-9]+)之间的管道。

POSIXly,你会这样做:

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