如何在 Linux 中使用 Column 格式化数据
Column 是一个免费的开源实用程序,通常作为 util-linux 软件包的一部分安装在所有最常见的 Linux 发行版中,因此即使是最小的安装也包含在内。使用此实用程序,我们可以按列组织文件内容或其他命令的输出,创建漂亮的表格,甚至生成 JSON 格式的文档。
在本教程中,我们将了解如何在 Linux 上使用“column”实用程序将文件内容格式化为表或 JSON。
在本教程中您将学习:
如何使用列将文件内容格式化为表格
如何命名列
如何指定输入分隔符
如何指定输出分隔符
如何将文件内容格式化为 JSON
将输出格式化为表格
正如我们在简介中所说,我们可以使用“列”实用程序来组织文件的内容或表中其他命令的输出。以下是该命令的一些实际用例。在类 Unix 操作系统上,/etc/fstab 文件包含有关启动时必须自动挂载的文件系统的信息。所述信息按列组织,每列包含特定信息。以下是该文件的一个最小示例:
#
# /etc/fstab
# Created by anaconda on Wed Nov 2 08:18:43 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rl-root / xfs defaults 0 0
UUID=2a9dc637-e858-407c-81dc-26ea16ac6c57 /boot xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0
正如您所看到的,/etc/fstab 文件中只包含两个文件系统,并且由于字符串长度不同,列没有很好地对齐。当然,从功能的角度来看,这并不相关,但它相当难看;我们可以使用“column”实用程序来“美化”它。
“column”命令接受输入文件的路径作为参数,但是,在这种情况下,我们希望在处理文件内容之前删除注释。为了完成这个任务,我们可以使用 sed 和 shell 管道:
$ sed /^#/d /etc/fstab | column --table
在上面的示例中,我们使用 --table
选项 (-t
) 调用“column”实用程序:这是创建表所必需的。这是我们得到的结果:
/dev/mapper/rl-root / xfs defaults 0 0
UUID=2a9dc637-e858-407c-81dc-26ea16ac6c57 /boot xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0
提供列名称
“列”产生的输出很好地对齐,但是,在某些情况下,我们可能需要添加一个包含列名称的附加“行”。为此,我们可以使用 --table-columns
选项 (-N
) 启动该实用程序,并将以逗号分隔的列名称列表作为参数传递。在这种情况下,我们可以运行:
$ sed /^#/d /etc/fstab | column --table --table-columns BLOCK_DEVICE,MOUNTPOINT,FILESYSTEM,MOUNT_OPTIONS,DUMP,FSCK_ORDER
上面的命令产生以下结果:
BLOCK_DEVICE MOUNTPOINT FILESYSTEM MOUNT_OPTIONS DUMP FSCK_ORDER
/dev/mapper/rl-root / xfs defaults 0 0
UUID=2a9dc637-e858-407c-81dc-26ea16ac6c57 /boot xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0
更改输入分隔符
默认情况下,“column”实用程序使用空格字符作为输入分隔符,以便按列组织文件的内容。这在某些情况下效果很好,就像我们在上一个示例中看到的那样,但是,有时我们可能需要指定不同的字符用作分隔符。例如,让我们看一下 /etc/passwd
文件中的信息是如何组织的。我们知道,这个文件是用来存储账户信息的;冒号字符(“:”)用于分隔每个条目中的字段:
tux:x:1000:1000:tux:/home/tux:/bin/bash
上面的行包含有关“tux”用户的信息。该行的第一个字段报告用户名。第二个字段用于密码:这里的x
表示密码经过哈希处理并存储在 /etc/shadow
文件中。第三和第四字段分别报告用户主要组的UID(用户ID)和GID(组ID)。第五个字段是所谓的GECOS 字段:它可以包含其他用户信息,例如他/她的全名或电话号码。第六个字段包含用户主目录的路径。相反,第七个也是最后一个字段包含有关默认 shell 或用户命令的信息,在本例中为“/bin/bash”。
为了在“漂亮”表格中格式化该文件的内容,我们必须告诉“column”实用程序使用“:”作为分隔符。我们可以通过 --separator
选项(-s
)来做到这一点:
$ column --table --separator=":" /etc/passwd
我们得到的结果如下:
root x 0 0 root /root /bin/bash
bin x 1 1 bin /bin /sbin/nologin
daemon x 2 2 daemon /sbin /sbin/nologin
adm x 3 4 adm /var/adm /sbin/nologin
lp x 4 7 lp /var/spool/lpd /sbin/nologin
sync x 5 0 sync /sbin /bin/sync
shutdown x 6 0 shutdown /sbin /sbin/shutdown
halt x 7 0 halt /sbin /sbin/halt
mail x 8 12 mail /var/spool/mail /sbin/nologin
operator x 11 0 operator /root /sbin/nologin
games x 12 100 games /usr/games /sbin/nologin
ftp x 14 50 FTP User /var/ftp /sbin/nologin
nobody x 65534 65534 Kernel Overflow User / /sbin/nologin
systemd-coredump x 999 997 systemd Core Dumper / /sbin/nologin
dbus x 81 81 System message bus / /sbin/nologin
polkitd x 998 996 User for polkitd / /sbin/nologin
avahi x 70 70 Avahi mDNS/DNS-SD Stack /var/run/avahi-daemon /sbin/nologin
rtkit x 172 172 RealtimeKit /proc /sbin/nologin
sssd x 997 993 User for sssd / /sbin/nologin
pipewire x 996 992 PipeWire System Daemon /var/run/pipewire /sbin/nologin
libstoragemgmt x 995 991 daemon account for libstoragemgmt /var/run/lsm /sbin/nologin
tss x 59 59 Account used for TPM access /dev/null /sbin/nologin
geoclue x 994 989 User for geoclue /var/lib/geoclue /sbin/nologin
cockpit-ws x 993 988 User for cockpit web service /nonexisting /sbin/nologin
cockpit-wsinstance x 992 987 User for cockpit-ws instances /nonexisting /sbin/nologin
rpc x 32 32 Rpcbind Daemon /var/lib/rpcbind /sbin/nologin
flatpak x 991 986 User for flatpak system helper / /sbin/nologin
colord x 990 985 User for colord /var/lib/colord /sbin/nologin
setroubleshoot x 989 984 SELinux troubleshoot server /var/lib/setroubleshoot /sbin/nologin
clevis x 988 983 Clevis Decryption Framework unprivileged user /var/cache/clevis /usr/sbin/nologin
gdm x 42 42 /var/lib/gdm /sbin/nologin
gnome-initial-setup x 987 982 /run/gnome-initial-setup/ /sbin/nologin
rpcuser x 29 29 RPC Service User /var/lib/nfs /sbin/nologin
sshd x 74 74 Privilege-separated SSH /usr/share/empty.sshd /sbin/nologin
chrony x 986 981 /var/lib/chrony /sbin/nologin
dnsmasq x 985 980 Dnsmasq DHCP and DNS server /var/lib/dnsmasq /sbin/nologin
tcpdump x 72 72 / /sbin/nologin
systemd-oom x 978 978 systemd Userspace OOM Killer / /usr/sbin/nologin
tux x 1000 1000 tux /home/tux /bin/bash
链接输出分隔符
正如我们所看到的,输入分隔符用于告诉“列”应使用哪个字符来按列组织文件的内容。相反,在命令的输出中使用输出分隔符来分隔各个字段。默认情况下,使用两个空格作为输出分隔符;为了使用不同的字符,我们必须将其作为参数传递给 --output-separator
选项 (-o
)。
在下面的示例中,我们使用 |
字符作为输出分隔符:
$ column --table --separator ":" --output-separator "|" /etc/passwd
我们获得:
root |x|0 |0 |root |/root |/bin/bash
bin |x|1 |1 |bin |/bin |/sbin/nologin
daemon |x|2 |2 |daemon |/sbin |/sbin/nologin
adm |x|3 |4 |adm |/var/adm |/sbin/nologin
lp |x|4 |7 |lp |/var/spool/lpd |/sbin/nologin
sync |x|5 |0 |sync |/sbin |/bin/sync
shutdown |x|6 |0 |shutdown |/sbin |/sbin/shutdown
halt |x|7 |0 |halt |/sbin |/sbin/halt
mail |x|8 |12 |mail |/var/spool/mail |/sbin/nologin
operator |x|11 |0 |operator |/root |/sbin/nologin
games |x|12 |100 |games |/usr/games |/sbin/nologin
ftp |x|14 |50 |FTP User |/var/ftp |/sbin/nologin
nobody |x|65534|65534|Kernel Overflow User |/ |/sbin/nologin
systemd-coredump |x|999 |997 |systemd Core Dumper |/ |/sbin/nologin
dbus |x|81 |81 |System message bus |/ |/sbin/nologin
polkitd |x|998 |996 |User for polkitd |/ |/sbin/nologin
avahi |x|70 |70 |Avahi mDNS/DNS-SD Stack |/var/run/avahi-daemon |/sbin/nologin
rtkit |x|172 |172 |RealtimeKit |/proc |/sbin/nologin
sssd |x|997 |993 |User for sssd |/ |/sbin/nologin
pipewire |x|996 |992 |PipeWire System Daemon |/var/run/pipewire |/sbin/nologin
libstoragemgmt |x|995 |991 |daemon account for libstoragemgmt |/var/run/lsm |/sbin/nologin
tss |x|59 |59 |Account used for TPM access |/dev/null |/sbin/nologin
geoclue |x|994 |989 |User for geoclue |/var/lib/geoclue |/sbin/nologin
cockpit-ws |x|993 |988 |User for cockpit web service |/nonexisting |/sbin/nologin
cockpit-wsinstance |x|992 |987 |User for cockpit-ws instances |/nonexisting |/sbin/nologin
rpc |x|32 |32 |Rpcbind Daemon |/var/lib/rpcbind |/sbin/nologin
flatpak |x|991 |986 |User for flatpak system helper |/ |/sbin/nologin
colord |x|990 |985 |User for colord |/var/lib/colord |/sbin/nologin
setroubleshoot |x|989 |984 |SELinux troubleshoot server |/var/lib/setroubleshoot |/sbin/nologin
clevis |x|988 |983 |Clevis Decryption Framework unprivileged user|/var/cache/clevis |/usr/sbin/nologin
gdm |x|42 |42 | |/var/lib/gdm |/sbin/nologin
gnome-initial-setup|x|987 |982 | |/run/gnome-initial-setup/|/sbin/nologin
rpcuser |x|29 |29 |RPC Service User |/var/lib/nfs |/sbin/nologin
sshd |x|74 |74 |Privilege-separated SSH |/usr/share/empty.sshd |/sbin/nologin
chrony |x|986 |981 | |/var/lib/chrony |/sbin/nologin
dnsmasq |x|985 |980 |Dnsmasq DHCP and DNS server |/var/lib/dnsmasq |/sbin/nologin
tcpdump |x|72 |72 | |/ |/sbin/nologin
systemd-oom |x|978 |978 |systemd Userspace OOM Killer |/ |/usr/sbin/nologin
tux |x|1000 |1000 |tux |/home/tux |/bin/bash
将内容格式化为 JSON
“column”实用程序的一个非常好的功能是能够将文件内容格式化为 JSON,使用列的内容作为值,使用列名称作为键。 --json
选项 (-J
) 用于完成此任务。仅当与 --table-columns
一起使用时,该选项才被接受,正如我们之前所见,它用于指定列名称:
$ column --table --separator=":" --table-columns username,password,uid,gid,gecos,home,shell --json /etc/passwd
这是上面命令产生的输出(我们方便地将其截断):
{
"table": [
{
"username": "root",
"password": "x",
"uid": "0",
"gid": "0",
"gecos": "root",
"home": "/root",
"shell": "/bin/bash"
},{
"username": "bin",
"password": "x",
"uid": "1",
"gid": "1",
"gecos": "bin",
"home": "/bin",
"shell": "/sbin/nologin"
},{
"username": "daemon",
"password": "x",
"uid": "2",
"gid": "2",
"gecos": "daemon",
"home": "/sbin",
"shell": "/sbin/nologin"
}, # remaining output truncated
]
}
正如您在上面看到的,与包含所有文件条目的列表关联的键称为“table”。我们可以通过使用 --table-name
选项 (-n
) 来更改它,并传递我们想要用作参数的名称。
结论
在本教程中,我们学习了如何使用“命令”实用程序将文件内容格式化为表或 JSON。我们了解了如何创建表、如何在命令生成的输出中提供和包含列名称以及如何指定输入和输出分隔符。最后,我们了解了如何将输出格式化为 JSON,使用列名作为键,将其内容作为值。我们还可以通过其他方式使用“列”来格式化文件内容。查看手册以了解所有内容!