具有公共字段的两个文件 - 是否可以根据另一个文件对一个文件进行排序?

具有公共字段的两个文件 - 是否可以根据另一个文件对一个文件进行排序?

假设我有两个具有共同字段的文件。我想根据此文件中找到的字段(例如数字字段)对第一个文件进行排序...但我希望这种重新排序也适用于其他文件 - 通过公共字段。

举个例子——完全地凭空抓起;-) -- 让我们拿/etc/密码/etc/影子

/etc/passwd:
(...)
sshd:x:124:65534::/var/run/sshd:/usr/sbin/nologin
sndiod:x:999:29::/var/lib/sndiod:/usr/sbin/nologin
dictd:x:125:135:Dictd 服务器,,,:/var/lib/dictd:/bin/false
postgres:x:126:136:PostgreSQL 管理员,,,:/var/lib/postgresql:/bin/bash
(...)
/etc/影子:
(...)
sshd:*:17055:0:99999:7:::
sndiod:!:17055::::::
字典:*:17055:0:99999:7:::
postgres:*:17055:0:99999:7:::
(...)

排序/etc/密码UID 上的数字很简单:

sort -n -t: -k3 /etc/passwd > pw

上面几行的结果是:

/etc/passwd:
(...)
sshd:x:124:65534::/var/run/sshd:/usr/sbin/nologin
dictd:x:125:135:Dictd 服务器,,,:/var/lib/dictd:/bin/false
postgres:x:126:136:PostgreSQL 管理员,,,:/var/lib/postgresql:/bin/bash
sndiod:x:999:29::/var/lib/sndiod:/usr/sbin/nologin
(...)

然而,/etc/影子不是有一个数字 UID 字段,我可以在之后排序...但是它确实如此 - 就像/etc/密码-- 有一个用户名字段...

那么有没有办法重新排序行/etc/影子这样用户名字段的顺序与中的用户名字段的顺序相同按数字排序 /etc/密码

  • 是否有一个命令 -sort或类似的东西 - 可以排序文件A在该文件中的某个键之后,同时排序文件B在两个文件共享的公共字段上?
  • 或者,是否有一个合适的两步过程 - 一个命令,一个 sed/AWK/Perl 脚本,或者其他东西 - 可以使用排序的文件A重新订购文件B在他们的共同领域之后?

答案1

连接文件,对合并的文件进行排序,然后删除不需要的列。

在这种情况下, 的字段 1/etc/passwd将与 的字段 1 连接/etc/shadow,并:作为字段分隔符。

join -t : -1 1 -2 1 /etc/passwd /etc/shadow |
sort -t : -k 3,3n |
cut -d : -f 1,8-

答案2

可能有一种更优雅的方法,但这里有一个两步方法:

for user in $(sort -n -t: -k3 /etc/passwd | cut -d: -f1)
do 
  grep ^${user}: /etc/shadow
done > /tmp/shadow.new

对于 /etc/passwd 中的每个条目,它都会读取一次 /etc/shadow。

答案3

我需要 sudo 来读取我的机器上的 /etc/shadow :

sudo awk -F: 'NR==FNR {uid[$1]=$3; next} {print uid[$1], $0}' /etc/passwd /etc/shadow |
 sort -n |
 cut -d" " -f2-

awk 脚本打印 passwd 文件中与影子文件中的用户名相对应的 uid,以空格分隔。然后按数字排序,然后通过 cut 命令删除 uid。

相关内容