将多个切割操作合并为一个

Combining multiple cuts operations into one

我有输入文件:

$ cat bleu.out 
BLEU = 16.67, 54.4/26.8/14.9/8.2 (BP=0.813, ratio=0.828, hyp_len=8982, ref_len=10844)
BLEU = 17.56, 55.1/27.6/15.8/9.4 (BP=0.804, ratio=0.821, hyp_len=8905, ref_len=10844)
BLEU = 17.95, 54.4/27.5/15.6/9.1 (BP=0.837, ratio=0.849, hyp_len=9206, ref_len=10844)
BLEU = 19.10, 54.8/28.1/16.3/9.7 (BP=0.860, ratio=0.869, hyp_len=9423, ref_len=10844)
BLEU = 19.29, 53.0/26.6/15.1/8.9 (BP=0.925, ratio=0.928, hyp_len=10058, ref_len=10844)
BLEU = 18.70, 55.7/28.7/16.4/9.4 (BP=0.839, ratio=0.851, hyp_len=9223, ref_len=10844)
BLEU = 18.63, 55.2/28.1/16.3/9.8 (BP=0.834, ratio=0.846, hyp_len=9178, ref_len=10844)
BLEU = 18.41, 54.2/27.4/15.5/9.2 (BP=0.857, ratio=0.867, hyp_len=9398, ref_len=10844)
BLEU = 18.70, 53.7/26.9/15.7/9.3 (BP=0.871, ratio=0.878, hyp_len=9526, ref_len=10844)

但是当我需要删除某一列时,比方说第一个逗号之后的第一列,我不得不使用多个 cut 实例,例如:

$ cat bleu.out | cut -f1 -d',' | cut -f3 -d ' '
16.67
17.56
17.95
19.10
19.29
18.70
18.63
18.41
18.70

有没有办法在一个 cut 实例中按顺序排列多个 cut 标准?例如。类似 cut-multi.sh -f1 -d',' -f3 -d' ' 的东西?

如果没有,还有什么其他方法可以执行cut -f1 -d',' | cut -f3 -d' '相同的操作?也欢迎使用 awksed 等。

以下使用 grep 和 perl 的环视功能的解决方案。这将打印 = 和第一个 , 之间的文本。

grep -oP '= \K.*?(?=,)' input
16.67
17.56
17.95
19.10
19.29
18.70
18.63
18.41
18.70

或向 Sundeep 建议:

 grep -oP '= \K[^,]+' input

您可以在 awk

中指定多个字段分隔符
$ awk -F'= *|,' '{print }' bleu.out
16.67
17.56
17.95
19.10
19.29
18.70
18.63
18.41
18.70
  • -F'= *|,' 指定 = 后跟零个或多个 space 或 , 作为字段分隔符
  • {print } 打印第二列

使用 sed:

$ sed 's/^[^=]*= \([^,]*\).*//' bleu.out
16.67
17.56
17.95
19.10
19.29
18.70
18.63
18.41
18.70

这会捕获在第一次出现 =(和 space)之后的所有非逗号到逗号 (\([^,]*\)) 的字符 (^[^=]*= ) 并将该行替换为捕获组 ().

另一个解决方案awk

awk '{sub(/,$/, "", ); print }' bleu.out

3rd 字段中删除最后一个 , 并打印它。

awk -F'[ = ,]' '{print }' file
16.67
17.56
17.95
19.10
19.29
18.70
18.63
18.41
18.70