J'ai un fichier contenant mes détails personnels (.txt). Comment puis-je, via le terminal, copier seulement quelques détails du fichier et les placer dans un nouveau fichier .txt
?
Par exemple, s'il s'agit du contenu du fichier:
name : farah age : 23 phone number : 0123 education : degree
comment puis-je copier uniquement l'âge et le numéro de téléphone et les exporter dans un nouveau fichier .txt
?
Il y a plusieurs moyens de le faire. Si votre fichier a une structure connue, vous pouvez utiliser grep
. La commande grep
recherche dans un fichier une phrase spécifique et renvoie les lignes correspondant à cette phrase. Donc, si votre fichier ressemble à
Nom: Sally
Date de naissance: 7.31.76
Adresse: 1234 Main St.
SSN: 123-45-6789
vous pouvez exécuter grep Name info.txt
et il retournera Name: Sally
. Vous pouvez alors rediriger la sortie vers un autre fichier. Donc appeler
grep Name info.txt > info2.txt
affichera la ligne dans le nouveau fichier info2.txt. Si vous voulez ajouter de nouvelles lignes, vous pouvez faire
grep Address info.txt >> info2.txt
sinon le fichier sera écrasé.
Vous pouvez également apprendre à utiliser un éditeur de texte en ligne de commande comme vim.
Vous pouvez utiliser grep pour rechercher un expression régulière dans details.txt et rediriger le résultat. au nouveau fichier.
Si toutes les lignes que vous voulez copier ont quelque chose en commun, les autres lignes ne peuvent pas être utilisées:
grep "string in common" details.txt > new.txt
Sinon, vous devrez rechercher chaque ligne que vous souhaitez copier, en utilisant toujours grep, et les ajouter à new.txt en utilisant >>
au lieu de >
.
Le fichier que vous avez montré contient tous les détails sur une seule ligne:
name : farah age : 23 phone number : 0123 education : degree
J'ai supposé que vous pouvez coder en dur age :
etc dans la commande, mais le texte qui le suit va varier et que les détails peuvent ne pas être dans l'ordre donné ou être contigus.
Vous pouvez extraire des parties de la ligne avec l'indicateur -o
de grep
name __. Cela n'imprime que la partie correspondante, plutôt que la ligne entière.
Si vous souhaitez inclure les parties age :
et phone number :
, vous pouvez utiliser l'indicateur -e
pour spécifier plusieurs correspondances ou alterner.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
L'expression [^ ]*
signifie un nombre quelconque de caractères qui ne sont pas un espace. Par conséquent, elle correspond aux caractères après le age :
jusqu'au prochain espace.
Remplacez file
par le nom du fichier contenant vos informations. Vous pouvez écrire le nouveau fichier en redirigeant la sortie vers un nouveau fichier avec l'opérateur >
, comme ceci:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Lorsque vous faites cela, vous ne verrez aucune sortie. Vous devriez d'abord vérifier la sortie, puis ajouter la redirection.
Voici l'exemple avec l'alternance. Nous utilisons l'indicateur -E
pour indiquer à grep
d'utiliser une expression régulière étendue. La syntaxe est (pattern1|pattern2)
- cela correspond à pattern1
et/ou pattern2
. Si l’un est trouvé, il sera imprimé (que l’autre soit trouvé ou non). J'utilise maintenant +
, qui signifie au moins un des caractères précédents, au lieu de *
, qui signifie zéro ou plus du caractère précédent. Dans ce contexte, les deux fonctionnent également bien.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
Si vous souhaitez omettre les parties age :
et phone number:
, vous pouvez utiliser l'indicateur -P
pour demander à grep
d'utiliser des expressions régulières compatibles Perl. Ceci prend en charge l’alternance, ainsi que la possibilité de faire correspondre du texte après un motif donné:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Si vous souhaitez formater le texte différemment, vous pouvez utiliser sed
name__, par exemple:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
Cela dépend de age
précédant phone number
, donc ajustez en conséquence si ce n'est pas le cas. Si vous ne pouvez pas compter sur la commande, vous pouvez utiliser cette commande très compliquée:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
Cela réorganise la ligne pour que la section phone number :
apparaisse en premier sur chaque ligne, puis effectue un deuxième remplacement pour sélectionner les détails souhaités. Je dois la technique utilisée ici à cette réponse par mur .
sed
non traitées dans les explications précédentes-r
utilise extended regex pour des commandes plus lisibles (GNU sed
comprend -E
avec le même sens)s/old/new/
remplace old
par new
name__(pattern)
enregistre pattern
pour référence ultérieure, avec \1
ou \2
etc (correspondant à l’ordre de gauche à droite dans lequel les groupes de capture se produisent - notez que sed
n'en conservera que 7 au maximum!)..
n'importe quel caractère, par conséquent, .*
représente un nombre quelconque de caractères.;
sépare les commandes, comme dans le shell.Il existe également des éditeurs qui fonctionnent dans le terminal, par exemple. nano, vi et emacs.
Si vous utilisez une interface utilisateur graphique sur votre machine locale et un terminal sur une machine distante, vous pouvez également utiliser la souris pour copier et coller d'une fenêtre/onglet de terminal à une autre.
En supposant que le fichier d'entrée details.txt
contienne:
name: farah
age: 23
phone number: 0123
education: degree
vous pouvez sélectionner les lignes "name" et "phone" par grep étendu et rediriger la sortie vers new.txt:
grep -E "age:|phone number:" details.txt > new.txt
Cela produira new.txt avec:
age: 23
phone number: 0123
Comment ça marche:
Grep n'imprime que des lignes correspondantes. Les options -E
activent l'expression rationnelle étendue, ce qui vous permet d'utiliser |
(alternative). Rappelez-vous de citer un motif complet, donc |
sera interprété par grep. Sinon, Shell tentera d'interpréter. Tu ne veux pas de ça ici.