Question Comment puis-je extraire une plage de lignes prédéterminée d'un fichier texte sur Unix?


J'ai un dump SQL ~ 23000 lignes contenant plusieurs bases de données. J'ai besoin d'extraire une certaine section de ce fichier (c'est-à-dire les données pour une seule base de données) et de le placer dans un nouveau fichier. Je connais les numéros de ligne de début et de fin des données que je souhaite.

Est-ce que quelqu'un connaît une commande Unix (ou une série de commandes) pour extraire toutes les lignes d'un fichier entre les lignes 16224 et 16482 par exemple, puis les rediriger dans un nouveau fichier?


412
2017-09-17 13:40


origine


Réponses:


sed -n '16224,16482p;16483q' filename > newfile

Du manuel sed:

p -       Imprimez l'espace de motif (sur la sortie standard). Cette commande est généralement utilisée uniquement avec l'option de ligne de commande -n.

n -       Si l'impression automatique n'est pas désactivée, imprimez l'espace de motif, puis remplacez l'espace de motif par la ligne suivante. Si   il n'y a plus d'entrée puis sed quitte sans traitement plus   commandes.

q -   Sortie sed sans traiter plus de commandes ou de saisie.   Notez que l'espace de motif courant est imprimé si l'impression automatique n'est pas désactivée avec l'option -n.

et

Les adresses d'un script sed peuvent prendre l'une des formes suivantes:

nombre       La spécification d'un numéro de ligne ne correspond qu'à cette ligne dans l'entrée.

Une plage d'adresses peut être spécifiée en spécifiant deux adresses   séparés par une virgule (,). Une plage d'adresses correspond à des lignes à partir de   où la première adresse correspond, et continue jusqu'à la seconde   correspondances d'adresse (inclusivement).


621
2017-09-17 13:42



sed -n '16224,16482 p' orig-data-file > new-file

Où 16224,16482 sont le numéro de ligne de début et le numéro de ligne de fin, inclusivement. C'est 1-indexé. -n supprime l'écho de l'entrée en sortie, ce que vous ne voulez manifestement pas; les chiffres indiquent la plage de lignes sur laquelle la commande suivante est utilisée; la commande p imprime les lignes pertinentes.


180
2017-09-17 13:46



Assez simple en utilisant tête / queue:

head -16482 in.sql | tail -258 > out.sql

en utilisant sed:

sed -n '16482,16482p' in.sql > out.sql

en utilisant awk:

awk 'NR>=10&&NR<=20' in.sql > out.sql

70
2017-09-17 13:46



Vous pouvez utiliser 'vi', puis la commande suivante:

:16224,16482w!/tmp/some-file

Alternativement:

cat file | head -n 16482 | tail -n 258

EDIT: - Juste pour ajouter une explication, vous utilisez tête -n 16482 afficher les 16482 premières lignes puis utiliser queue -n 258 pour obtenir les 258 dernières lignes sur la première sortie.


21
2017-09-17 13:42



Il y a une autre approche avec awk:

awk 'NR==16224, NR==16482' file

Si le fichier est énorme, il peut être bon de exit après avoir lu la dernière ligne souhaitée. De cette façon, il ne lira pas inutilement le fichier jusqu'à la fin:

awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file

19
2018-01-14 16:30



perl -ne 'print if 16224..16482' file.txt > new_file.txt

13
2017-09-17 13:43



 # print section of file based on line numbers
 sed -n '16224 ,16482p'               # method 1
 sed '16224,16482!d'                 # method 2

7
2017-09-17 13:42



sed -n '16224,16482p' < dump.sql


5
2017-09-17 13:45



cat dump.txt | head -16224 | tail -258

devrait faire le tour. L'inconvénient de cette approche est que vous devez faire l'arithmétique pour déterminer l'argument pour la queue et pour expliquer si vous voulez que le 'entre' inclue la ligne de fin ou non.


5
2017-09-17 13:49



Rapide et sale:

head -16428 < file.in | tail -259 > file.out

Probablement pas la meilleure façon de le faire mais ça devrait marcher.

BTW: 259 = 16482-16224 + 1.


3
2017-09-17 13:44