example.txt est ci-dessous
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911
Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911
J'utilise le script bash et disons que je veux rechercher un restaurant par son nom dans le fichier ci-dessus. Demandez à l'utilisateur d'entrer le nom du restaurant et il devrait imprimer les informations concernant ce restaurant (5 lignes).
awk '/McDonalds/> /KFC/' example.txt
Je sais que la ligne de code ci-dessus imprimera toute la ligne correspondant au modèle "McDonalds" et "KFC", mais imprimera simplement la 1ère ligne du fichier texte, mais pas le reste des informations concernant ce restaurant. Comment puis-je lui dire d'imprimer toutes les informations (5 lignes) à partir de la seule entrée utilisateur du nom du restaurant?
Avec awk, vous pouvez changer le séparateur record. Par défaut, c'est une nouvelle ligne, chaque ligne du fichier est donc un enregistrement. Si vous définissez la variable RS
sur la chaîne vide, awk considérera que les enregistrements sont séparés par des lignes vides:
awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt
Utilisation de sed
:
$ sed -n '/KFC/,/^$/p' file
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911
$ sed -n '/McDo/,/^$/p' file
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911
C’est la fonction sed
de base, vous pouvez vous référer SCRIPTS UTILES À UNE LIGNE POUR SED
# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p' # case sensitive
$ awk '$2=="KFC" {print; for(i=1; i<=4; i++) { getline; print}}' example.txt
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911
La commande ci-dessus va obtenir et imprimer les 4 lignes consécutives avec la ligne en cours car elle a été introduite dans une boucle for.Le motif de recherche $2=="KFC"
permet d'obtenir une ligne particulière à partir de plusieurs lignes.
Une autre solution possible:
awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt
Il suffit d’imprimer de la ligne contenant le nom souhaité à la dernière ligne contenant Word Phone
(en supposant bien sûr que toutes les entrées suivent le même modèle et que Phone
sera toujours le dernier enregistrement)
$> awk '/5 guys/,/Phone/' restaurants.txt
Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911
$> awk '/McDonalds/,/Phone/' restaurants.txt
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911
Si nous voulions compliquer un peu les choses, nous pourrions imprimer exactement 5 lignes après le match, comme ceci:
awk '/McDonalds/{stop=NR+5}; NR<=stop ' restaurants.txt
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911
La variable stop
ne sera pas définie, donc NR<=stop
n'imprimera rien, jusqu'à ce que la partie /McDonalds/{stop=NR+5;}
définisse réellement la variable, et cela ne se produira que lorsque nous aurons trouvé la correspondance.