Dois arquivos com um campo comum - é possível classificar um baseado no outro?

1

Digamos que eu tenha dois arquivos com um campo comum. Eu quero classificar o primeiro baseado em um campo (por exemplo, um campo numérico) encontrado neste arquivo ... mas eu quero que este reordenamento se aplique ao outro arquivo também - através do campo comum.

Para dar um exemplo - completamente tirado do nada ;-) - vamos pegar o / etc / passwd e o / etc / shadow :

/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 Server,,,:/var/lib/dictd:/bin/false
postgres:x:126:136:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
(...)
/etc/shadow:
(...)
sshd:*:17055:0:99999:7:::
sndiod:!:17055::::::
dictd:*:17055:0:99999:7:::
postgres:*:17055:0:99999:7:::
(...)

Classificar / etc / passwd numericamente no UID é fácil:

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

Qual das linhas acima gera:

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

No entanto, / etc / shadow não tem um campo UID numérico que eu possa classificar depois ... Ele faz no entanto - como / etc / passwd - tem um campo de nome de usuário ...

Então existe uma maneira de reordenar as linhas em / etc / shadow para que o campo username tenha a mesma ordem que o campo username no numericamente classificado / etc / passwd ?

  • Existe um comando - sort ou algo similar - que pode ordenar o arquivo A depois de alguma chave naquele arquivo, e simultaneamente classificar arquivo B em um arquivo campo comum compartilhado pelos dois arquivos?
  • Como alternativa, existe um processo de duas etapas adequado - um comando, um script sed / AWK / Perl ou algo assim - que pode usar o arquivo classificado para reordenar? arquivo B depois do campo em comum?
por Baard Kopperud 17.09.2016 / 00:00

3 respostas

3

Junte os arquivos, classifique o arquivo combinado e retire as colunas que você não deseja.

Nesse caso, o campo 1 de /etc/passwd deve ser unido ao campo 1 de /etc/shadow , com : como o separador de campo.

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

Pode haver uma maneira mais elegante, mas aqui está um método de duas etapas:

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

Ele lê / etc / shadow uma vez para cada entrada em / etc / passwd.

    
por 17.09.2016 / 03:50
0

Eu preciso do sudo para ler / etc / shadow na minha máquina:

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

O script awk imprime o uid do arquivo passwd correspondente ao nome de usuário no arquivo shadow, separado por um espaço. Em seguida, ele é classificado numericamente e, em seguida, o uid é descartado pelo comando cut.

    
por 17.09.2016 / 16:23