我将空格更改为制表符的 awk 程序不起作用

Hos*_*ost 4 awk text-processing

如何编写awk用于读取数据文件students.txt并以选项卡格式输出数据的shell脚本,如下所示:

Surname Forename MSc Stream Date of Birth
Smith John IT 15.01.1986
Taylor Susan IT 04.05.1987
Thomas Steve MIT 19.04.1986
Run Code Online (Sandbox Code Playgroud)
  • 如果选项卡式列不对齐,请不要担心。

  • 每个(姓氏、名字、理学硕士专业和出生日期)列之间的距离是一个选项卡。

题:

为什么这个波纹管代码对我不起作用?

awk 'BEGIN {IFS=" "} {OFS="\t"} {print $1,$2,$3,$4}' students.txt
Run Code Online (Sandbox Code Playgroud)

Sie*_*geX 7

awk '{$1=$1}1' OFS="\t" students.txt
Run Code Online (Sandbox Code Playgroud)

概念证明

$ awk '{$1=$1}1' OFS="\t" students.txt
Surname Forename        MSc     Stream  Date    of      Birth
Smith   John    IT      15.01.1986
Taylor  Susan   IT      04.05.1987
Thomas  Steve   MIT     19.04.1986
Run Code Online (Sandbox Code Playgroud)

解释

它不起作用的原因是因为awk在应用新的输出字段分隔符之前需要更改其中一个字段。此缺陷 (恕我直言) 的解决方法是为其自身设置一个字段,因此$1=$1


对于这种简单类型的更改,您最好使用trsed

tr -s ' \t' '\t*' < students.txt
sed 's/[[:space:]]\+/\t/g' students.txt
Run Code Online (Sandbox Code Playgroud)

  • 问题中的代码也有效(至少在 GNU 和 FreeBSD 实现上)。您描述的“缺陷”可能会发生,因为 `print` 打印 $0 并且 $0 在没有任何更改时不会使用新的 OFS 重建。不确定这种行为是错误还是真的应该这样工作。但是 `print $1,$2,$3,$4` 仍然使用 OFS 来分隔字段。 (2认同)