我有以下列标题:
EntryDate,HH_ID,HH_type,ID#,Age,First,Last,Gender,Race,Ethnicity,CaseWorkerName
Run Code Online (Sandbox Code Playgroud)
大约有 2000 行数据非常匹配。
我想排序CaseWorkerName
并将其他列中的所有值排列起来。
实现这一目标的最佳方法是什么?
这CaseWorkerName
是第 11 列。sort
实用程序可能会被告知要根据哪一列进行排序,以及在指定列时使用什么分隔符:
$ sort -t ',' -k11,11 data.in
Run Code Online (Sandbox Code Playgroud)
这将告诉sort
使用逗号作为分隔符,并根据第 11 到 11 列(即仅第 11 列)按字典顺序升序排序。
输出被写入控制台。如果要将输出存储在另一个文件中,请使用
$ sort -t ',' -k11,11 -o data.out data.in
Run Code Online (Sandbox Code Playgroud)
data.in
如果使用-o
标志来指定输出文件是可以的。
如果您希望避免对第一行进行排序(它可能包含列标题),那么我们必须首先将标题与数据分开:
$ head -n 1 data.in >data.header
$ sed '1d' data.in >data.unsorted
Run Code Online (Sandbox Code Playgroud)
然后将排序后的数据与标题进行排序和重新组合:
$ sort -t ',' -k1,11 -o data.sorted data.unsorted
$ cat data.header data.sorted >data.out
$ rm data.sorted data.header data.unsorted
Run Code Online (Sandbox Code Playgroud)
或者,更短
$ sed '1d' data.in | sort -t ',' -k11,11 -o data.sorted
$ head -n 1 data.in | cat - data.sorted >data.out
$ rm data.sorted
Run Code Online (Sandbox Code Playgroud)
如果您在使用 GNU coreutils 的 Linux 系统上,这可能会更短,
$ ( head -n 1; sort -t ',' -k11,11 ) <data.in >data.out
Run Code Online (Sandbox Code Playgroud)
使用 GNU coreutils 实现head
,子进程 ( (...)
)的标准输入将首先被消耗,head
而任何剩余的数据将被提供给sort
。子流程的输出将是 的输出,head
然后是 的输出sort
。
在其他系统上,head
可能会从标准输入流中消耗比预期更多的sort
东西,这将不提供任何东西(或至少不提供文件的其余部分)。至少在 OpenBSD 上是这样。
结果在data.out
上面的每个示例之后。
请注意,如果任何列中的数据包含逗号,所有这些方法都将失败...