Récupérer certains contenus d'un fichier

9

Je sais donc que des outils existent pour ce problème parce que j'en ai entendu parler, mais je ne sais pas ce qu'ils sont.

Je veux faire quelque chose comme filtrer toutes les données, mais les noms d'utilisateur dans / etc / passwd.

Par exemple, je voudrais récupérer user1, user2 et user3 dans le fichier suivant. Dans ce cas, la logique pourrait être "Saisir le texte jusqu'au premier ':' sur chaque ligne du fichier".

user1:x:1:4
user2:x:2:5
user3:x:3:6

La sortie serait:

user1
user2
user3
mouche
la source

Réponses:

19

cutexiste exactement dans ce but. L' -dindicateur spécifie le délimiteur et -fspécifie les champs à afficher:

cut -d: -f1 /etc/passwd

L'argument to -fpeut être quelque chose comme 1,3pour montrer les premier et troisième champs, ou 1-3pour montrer les trois premiers; il y a aussi des drapeaux -bet -cpour lire les octets et les caractères au lieu des champs. Si vous avez besoin de quelque chose de plus flexible, généralement awkfera l'affaire (voir la réponse de Matthew )

Michael Mrozek
la source
13

Chaque fois que vous voulez extraire des données d'une entrée tabulaire, vous devriez considérer awk . Il est disponible sur pratiquement tous les systèmes Unix, c'est donc une bonne habitude à prendre:

awk -F':' '{print $1}' /etc/passwd 
  • -F':': définit ":" comme délimiteur de colonne.
  • '{}': exécutez cette instruction pour chaque ligne.
  • print $1: imprimer la première colonne à l'écran.
Matthew Brannigan
la source
3
Note aléatoire: awkprend un nom de fichier, vous pouvez donc sauter la pipe et faireawk -F: '{print $1}' /etc/passwd
Michael Mrozek
Il me semble toujours oublier que awk prend un nom de fichier, je semble toujours l'utiliser dans un pipeline ... quelque chose comme sed | awk etc ...
Matthew Brannigan
presque tout ce qui fonctionne avec des fichiers prend un nom de fichier ( tret atsont quelques exemples des quelques choses qui ne le font pas).
pause jusqu'à nouvel ordre.
3

Voici une doublure Perl:

perl -F/:/ -lane 'print $F[0]' /etc/passwd
Zaid
la source
1

Sous perl et awk, il existe un troisième outil pour de tels travaux, qui est sed:

sed 's/:.*//' FILE 

Il s'agit de la commande de substitution: substitute from colon:, suivie d'un point, qui est un joker pour les caractères de toute nature, de tout nombre (*), sans rien.

Il s'agit de '(ubstitute) / FROM / TO /' avec TO étant vide, ce qui signifie 'supprimer tout du premier (car sed est par défaut gourmand) deux points (jusqu'à la fin de la ligne, car sed fonctionne bien avec des lignes entières).

Bien sûr, cutc'est aussi une bonne commande, mais je dirais d'une famille différente.

Utilisateur inconnu
la source
1

Dans votre exemple, les 3 noms sont tous de la même longueur. Dans de tels cas - ce qui pourrait arriver, mais ce n'est pas si probable avec / etc / passwd - vous pourriez aussi utiliser colrm:

echo "user1:x:1:4
> user2:x:2:5
> user3:x:3:6" | colrm 6
user1
user2
user3

ou bien sûr

cat FILE | colrm 6 

(un cas rare où useless use of catne s'applique pas, car vous ne pouvez pas remettre un fichier à la main pour agir en tant que paramètre.)

Utilisateur inconnu
la source
catest toujours là inutile: colrm 6 < FILE.
manatwork
Eh bien, oui, mais pas si inutile, comme pour appeler cat foo | grep bar.
utilisateur inconnu
1

Juste pour être complet, il n'y a pas besoin de commandes externes, le shell (Bourne shell ou compatible) peut le gérer seul:

while IFS=':' read -r needed garbage; do echo "$needed"; done < input_file

Bien sûr, c'est probablement la plus lente de toutes les solutions possibles, alors pour les fichiers volumineux, choisissez-en une autre.

homme au travail
la source