我有一个文本文件,必须在其中剪切字段 3、4、5 和 8:
219 432 4567 Harrison Joel M 4540 Accountant 09-12-1985
219 433 4587 Mitchell Barbara C 4541 Admin Asst 12-14-1995
219 433 3589 Olson Timothy H 4544 Supervisor 06-30-1983
219 433 4591 Moore Sarah H 4500 Dept Manager 08-01-1978
219 431 4527 Polk John S 4520 Accountant 09-22-1998
219 432 4567 Harrison Joel M 4540 Accountant 09-12-1985
219 432 1557 Harrison James M 4544 Supervisor 01-07-2000
由于默认分隔符是制表符,因此提取字段的命令为:
cut -f 3,4,5,8 filename
问题是输出与原始文件内容相同。这里发生了什么?为什么这不起作用?
答案1
并非所有列之间的空格看起来都是制表符,因此cut
无法执行您想要的操作。我建议awk
改为使用。它比cut
解析数据列(例如您想要完成的任务)更灵活:
$ awk '{print $3,$4,$5,$8}' data.txt
例子
$ awk '{print $3,$4,$5,$8}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
您还可以使用以下命令来间隔输出column
:
$ awk '{print $3,$4,$5,$8}' data.txt |column -t
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
您还可以仅使用awk
和 来完成所有操作printf
:
$ awk '{printf "%s\t%-20s\t%s\n",$3,$4" "$5,$8}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
重新审视剪辑
上述方法做得很好,但它们不处理特定列的值中存在空格的任何行。例如,包含“Dept Manager”的行被截断为“Dept”。
如果可以保证数据是如图所示的结构,我们可以使用,cut
但我们可以只使用字符的实际位置来显示,而不是在分隔符上分割。
例子
这将从文件中剪切文本data.txt
并打印位置 9 到 13、14 到 35 等位置的所有内容。
$ cut -c 9-13,14-35,43-58 data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin Asst
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept Manager
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
重温 awk
还可以使 awk 根据文本的位置而不是分隔符来提取文本。虽然它更详细,但为了完整起见,这里是如何实现的。
$ awk '{
printf "%s\t%-20s\t%s\n",substr($0,9,5),substr($0,14,22),substr($0,43,16)
}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin Asst
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept Manager
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
awk 字段宽度
如果您使用的是 GNU 的变体,awk
则可以使用该变量FIELDWIDTHS
来指定每个字段的静态大小。substr
如果您有权访问它,那么这比该方法要干净得多。您还可以有效地将原本会被解析为单独字段的字段粘合在一起。
$ awk 'BEGIN { FIELDWIDTHS="4 4 5 24 5 16 11" }{ print $3,$4,$5,$6 }' data.txt
4567 Harrison Joel M 4540 Accountant
4587 Mitchell Barbara C 4541 Admin Asst
3589 Olson Timothy H 4544 Supervisor
4591 Moore Sarah H 4500 Dept Manager
4527 Polk John S 4520 Accountant
4567 Harrison Joel M 4540 Accountant
1557 Harrison James M 4544 Supervisor
答案2
我的猜测是我不认为这些是标签。我不认为它们是选项卡的原因是因为当我复制粘贴文件并手动对字段进行制表时,似乎cut -f 3,4,5,8 filename
工作正常。cat filename | awk '{print $3, $4, $5, $8}'
如果您不想重新制作字段和值,您最好这样做。