J'ai un fichier contenant une liste d'utilisateurs et d'informations, chaque ligne est un utilisateur distinct écrit comme suit:
alfred,butler,male,70,7:15.
Je veux récupérer les noms uniquement dans la liste afin de pouvoir créer un utilisateur pour eux.
Une fois que j'ai les noms, je peux simplement utiliser une boucle for et faire écho à useradd avec chacun des noms d'utilisateur, puis simplement copier et coller le texte. Comment puis-je aborder en saisissant les caractères avant la première virgule?
Il est facile d'extraire les noms: utilisez awk avec le drapeau -F
pour imprimer le premier champ
awk -F, '{print $1}' input.csv
Afin d'ajouter réellement des utilisateurs, vous devez lire la sortie de awk, ligne par ligne. Une façon de faire est de montrer Zanna, avec pipe à while read variable ; do . . . done
.
Une alternative serait de tirer parti de la fonction system()
de awk pour créer d'abord une commande et la transmettre à la fonction. Considère ceci:
$ awk -F ',' '{command=sprintf("useradd \"%s\"",$1);print command }' input.txt
useradd "alfred"
useradd "johnny"
Pour chaque ligne, nous extrayons le premier mot et le plaçons dans useradd "%s"
. Cela peut être donné à la fonction system()
qui fonctionnera avec /bin/sh
En cours d'exécution en tant que root:
$ awk -F ',' '{command=sprintf("useradd \"%s\" ",$1); system(command) }' input.txt
$ grep 'alfred' /etc/passwd
alfred:x:1001:1001::/home/alfred:
CAUTION: system()
appelle /bin/sh
, qui sous Ubuntu est un lien symbolique vers /bin/dash
. Donc, évitez bashismes dans la commande que vous passez
Vous pouvez utiliser cut
pour saisir le premier champ, puis canaliser vers une boucle while
pour exécuter des commandes avec les noms en entrée:
cut -d ',' -f1 file | while read line; do echo "$line"; done
évidemment, ce script ne fait rien d’utile en tant que tel - remplacez echo
par ce que vous voulez faire pour chaque nom, par exemple Sudo useradd
(après le test avec echo
)
-d ','
utilise une virgule comme délimiteur (d
)-f1
le premier (1
) champ (f
)while read line
lecture du fichier, boucle sur chaque ligne en tant que variable $line
do <command> "$line"
exécuter <command>
sur l'argument développé à partir de la variable (c'est-à-dire sur chaque ligne de la sortie transmise)