2017-06-24 1 views
-1

Je souhaite mettre en forme la sortie d'un compte d'utilisateur de /etc/passwd pour afficher uniquement le nom, le rôle et le chemin de répertoire, tous séparés par des virgules. Je sais que cela devrait être facile, mais pour la vie de moi je ne peux pas comprendre comment afficher entre certains deux-points. (Notez que cela devrait fonctionner avec un nom d'utilisateur, non seulement l'ex)Comment mettre en forme la sortie d'un compte utilisateur à partir de/etc/passwd

Ex de grep joe /etc/passwd:

joe:x:1001:1001:System Admin:/home/joe:/bin/bash 

souhaité Sortie:

joe, System Admin, /home/joe 

Merci!

+0

-t-il être bash? Généralement, la commande 'awk' est utilisée pour de telles manipulations, mais la manipulation de chaînes est plus simple dans' ruby' par exemple. Vous pouvez exécuter 'ruby' aussi depuis la ligne de commande, je peux vous envoyer une solution en ruby ​​si vous le souhaitez. – Rubycut

Répondre

2

Essayez:

grep joe /etc/passwd | cut -d: -f1,5,6 

Si vous vraiment besoin "" comme séparateur:

grep "^joe:" /etc/passwd | cut -d: -f1,5,6 | tr : , 

Le "^" assure correspond uniquement à de "Joe" au début de la ligne sont interceptés (Merci PSkocik pour le rappel). grep par défaut accepte un regex.

Traduction en bash, mais deux lignes:

x=`grep joe /etc/passwd | cut -d: -f1,5,6` 
echo ${x/:/,} 
+0

Ça a bien marché. Si cela ne vous dérange pas de demander, comment cela fonctionne-t-il? Deviner cela a quelque chose à voir avec la coupe du 1er, 5ème et 6ème contenu entre les deux-points? – Eric

+0

Étant donné que les deux versions aboutissent à trois processus, je préférerais la version pure-POSIX. BTW, vous devriez grep pour '^ joe:', pas 'joe'. – PSkocik

+0

@Eric Les commandes 'cut' lisent dans un fichier ligne par ligne, coupant au délimiteur' -d' et sortant seulement le champ '-f'. Lorsque vous utilisez piping - '|' - qui est quelque chose que vous ** devez ** vous familiariser avec, le 'fichier' est en fait 'stdin', qui est" piped "à partir de la commande précédente' 'grep' - recevoir comme " fichier "le' stdout' de 'grep. Le deuxième tuyau à tr traduit ":" à "," dans chaque ligne d'une manière similaire. – kabanus

5
awk 'BEGIN{ FS=":"; OFS=", " } $1=="joe" { print $1,$5,$6; exit }' /etc/passwd 

(mais vous devriez montrer un peu plus d'effort la prochaine fois - votre question est très downvotable :))

4

Avec l'aide cut virgule comme --output-delimiter:

cut -d: -f1,5,6 --output-delimiter=, /etc/passwd 
+2

Je ne connaissais pas 'output-delimiter' - merci! – kabanus

0

Si vous voulez le faire purement dans shel l (sh POSIX suffit, Bash pas nécessaire), puis read est votre ami:

while IFS=: read user pw uid gid gecos home shell ; do 
    if [ "$user" = "joe" ] ; then 
     echo "$user, $gecos, $home" 
    fi 
done < /etc/passwd 
+0

Légère variation: 'grep joe/etc/passwd | alors que IFS =: read -r u xid gid n h s; fais écho "$ u, $ n, $ h"; fait ' –

+0

@ DavidC.Rankin, j'irais avec' grep '^ joe:' 'juste pour la rigueur générale – ilkkachu

+0

D'accord, pas besoin de ne pas ancrer et terminer. J'aime ta réponse. J'ai pris votre avis et mis à jour le mien ': p' –

0

Ajout aux variations, dans bash, vous pouvez diriger la sortie de grep directement à une accolade fermée read et séparer la champs utilisant IFS selon les besoins. En utilisant des noms courts pour les champs, vous pouvez faire:

grep '^joe:' /etc/passwd | 
{ IFS=: read -r u x uid gid n h s; echo "$u, $n, $h"; } 

qui donnerait à la sortie que vous cherchez (si /etc/passwd contenait l'entrée)