Contents

在Linux命令行中向给定的TSV文件添加新列

1. 概述

我们经常使用制表符分隔值 (TSV) 文件来存储或传输数据。TSV 文件是基于列的。

在本教程中,我们将探讨如何在 Linux 命令行中向给定的 TSV 文件添加新列。

2. 问题介绍

像往常一样,让我们通过一个例子来理解这个问题。假设我们有一个名为employee.tsv的 TSV 文件:

$ cat employee.tsv
Name    Gender  Age Department
Eric    Male    31  Marketing
Kevin   Male    32  Sales
Kent    Male    33  Development
Amanda  Female  30  HR

cat输出所示,employee.tsv文件有四列。如果我们想向这个文件中添加一个新列,有三种情况:

  • 在第一列之前插入一个新列
  • 在最后一列之后添加一个新列
  • 在原始列的中间插入一个新列

本教程将涵盖所有三种情况。

此外,由于awk 命令是一个强大的命令行文本处理实用程序并且擅长处理基于列的数据,因此我们将使用awk命令来添加列。

接下来,让我们看看如何使用awk添加列。

3. 在第一列之前添加一列

假设我们要在employee.tsv文件的第一列“Name”之前添加一个新列“ ID ” 。

设置awk命令的FSOFS 变量允许我们控制如何解析记录和输出结果。由于我们的输入和输出都是 TSV 格式,我们可以将 FS 和 OFS 设置为具有相同的值:a Tab

此外,由于我们计划在所有其他列之前插入一个新列,因此以下awk命令将完成这项工作:

awk 'BEGIN{ FS = OFS = "\t" } { print "NewColumn", $0 }' input.tsv

现在,让我们看看我们的 employee.tsv文件。首先,我们要向其中插入一个“ ID ”列。

此外,在文件中,我们有一个标题行,因此我们需要检查当前记录是否是标题行 并将标题“ ID ”放在那里:

$ awk 'BEGIN{ FS = OFS = "\t" } { print (NR==1? "ID" : NR-1), $0 }' employee.tsv
ID	Name    Gender  Age Department
1	Eric    Male    31  Marketing
2	Kevin   Male    32  Sales
3	Kent    Male    33  Development
4	Amanda  Female  30  HR

正如 上面的awk命令所示,我们正在遵循我们已经总结的命令模式,并在最前面获得一个新的“ ID ”列。为简单起见,我们将他们的记录序列号指定为他们的ID

值得一提的是,即使awk命令产生了预期的输出,文件内容并没有改变。

我们可以使用临时文件来保存awk 的更改

$ awk 'BEGIN{ FS = OFS = "\t" } { print (NR==1? "ID" : NR-1), $0 }' employee.tsv > tmp && mv tmp employee.tsv 
$ cat employee.tsv
ID	Name    Gender  Age Department
1	Eric    Male    31  Marketing
2	Kevin   Male    32  Sales
3	Kent    Male    33  Development
4	Amanda  Female  30  HR

接下来,让我们看看如何将新列附加到 TSV 文件:

4. 最后添加一个新列

我们已经讨论了将列首先添加到 TSV 文件的一般命令模式。我们可以交换“ NewColumn ”和“ $0 ”以附加“ NewColumn

awk 'BEGIN{ FS = OFS = "\t" } { print $0, "NewColumn" }' input.tsv

接下来,让我们将“ HiringYear ”列附加到我们的employee.tsv文件中。为简单起见,我们假设所有员工都在同一年( 2022 年)受雇:

$ awk 'BEGIN{ FS = OFS = "\t" } { print $0, (NR==1? "HiringYear" : "2022") }' employee.tsv > tmp && mv tmp employee.tsv
$ cat employee.tsv
ID	Name    Gender  Age Department	HiringYear
1	Eric    Male    31  Marketing	2022
2	Kevin   Male    32  Sales   2022
3	Kent    Male    33  Development	2022
4	Amanda  Female  30  HR	    2022

同样,在上面的awk命令中,我们进行了相同的检查以区分当前记录是标题行还是常规数据记录。

接下来,我们来探讨一下如何在中间添加一列。

5. 在原来的中间增加一个新的列

假设我们希望在“Age”和“Department”列之间有一个新列“Role” 。由于新列位于列的中间,我们不能像以前那样在awk命令中简单地使用*$0*变量。

解决该问题的一个想法是用制表符分隔的新列值扩展相邻的列值。所以,如果我们想在第 x列之后添加一个新列,命令如下所示:

awk 'BEGIN{ FS = OFS = "\t" } { $x = $x FS "NewColumn" }1' input.tsv

当然,我们可以在之后扩展列:

awk 'BEGIN{ FS = OFS = "\t" } { $(x+1) = "NewColumn" FS $(x+1) }1' input.tsv

现在,让我们看看我们的例子。为简单起见,假设文件中的所有员工都是“Manager”角色。

在我们的示例中,“Age”列是原始输入文件中的第四列。因此,我们可以按照我们讨论过的命令模式来解决问题:

$ awk 'BEGIN{ FS=OFS="\t" } {$4 = $4 FS (NR==1? "Role" : "Manager") }1' employee.tsv > tmp && mv tmp employee.tsv
$ cat employee.tsv
ID	Name	Gender	Age	Role	Department	HiringYear
1	Eric	Male	31	Manager	Marketing	2022
2	Kevin	Male	32	Manager	Sales	2022
3	Kent	Male	33	Manager	Development	2022
4	Amanda	Female	30	Manager	HR	2022