J'ai un vidage SQL de ~ 23000 lignes contenant plusieurs bases de données pour des données. J'ai besoin d'extraire une certaine section de ce fichier (c'est-à-dire les données d'une seule base de données) et de la placer dans un nouveau fichier. Je connais les numéros de ligne de début et de fin des données que je veux.
Quelqu'un connaît-il une commande Unix (ou une série de commandes) pour extraire toutes les lignes d'un fichier entre disons les lignes 16224 et 16482, puis les rediriger dans un nouveau fichier?
unix
command-line
sed
text-processing
Adam J. Forster
la source
la source
Réponses:
Du manuel sed :
et
la source
sed -n '16224,16482p;16483q' filename
. Sinon sed continuera à scanner jusqu'à la fin (ou du moins ma version le fait).Où 16224,16482 sont le numéro de ligne de départ et le numéro de ligne de fin, inclus. Ceci est indexé 1.
-n
supprime l'écho de l'entrée comme sortie, ce que vous ne voulez clairement pas; les nombres indiquent la plage de lignes sur laquelle exécuter la commande suivante; la commandep
imprime les lignes pertinentes.la source
sed -n '16224,16482p;16482q' orig-data-file > new-file
.Assez simple avec tête / queue:
en utilisant sed:
en utilisant awk:
la source
tail
.sed -n 16224,16482p' in.sql >out.sql
et la commande awk devrait êtreawk 'NR>=16224&&NR<=16482' in.sql > out.sql
head -16482 in.sql | tail -$((16482-16224)) >out.sql
laisse le calcul à bashtail -n +16224
pour réduire le calculVous pouvez utiliser 'vi' puis la commande suivante:
Alternativement:
EDIT: - Juste pour ajouter une explication, vous utilisez head -n 16482 pour afficher les premières 16482 lignes puis utilisez tail -n 258 pour extraire les 258 dernières lignes de la première sortie.
la source
cat
commande;head
peut lire un fichier directement. C'est plus lent que de nombreuses alternatives car il utilise 2 (3 comme indiqué) commandes où 1 est suffisant.cat
). D'autres solutions nécessitent au moins quelques minutes. La variation la plus rapide sur GNU semble également êtretail -n +XXX filename | head XXX
.Il existe une autre approche avec
awk
:Si le fichier est volumineux, il peut être utile de
exit
lire la dernière ligne souhaitée. De cette façon, il ne lira pas inutilement les lignes suivantes:la source
print; exit
. Merci !awk 'NR==16224, NR==16482; NR==16482 {exit}' file
la source
la source
devrait faire l'affaire. L'inconvénient de cette approche est que vous devez effectuer l'arithmétique pour déterminer l'argument de queue et pour savoir si vous voulez que «entre» inclue la ligne de fin ou non.
la source
cat
commande;head
peut lire un fichier directement. C'est plus lent que de nombreuses alternatives car il utilise 2 (3 comme indiqué) commandes où 1 est suffisant.| tail -$((16482 - 16224))
.Debout sur les épaules de boxxar, j'aime ça:
par exemple
Cela
$
signifie "dernière ligne", donc la première commande faitsed
imprimer toutes les lignes commençant par la ligne16224
et la deuxième commande faitsed
quitter après l' impression de la ligne16428
. (Ajout1
pour leq
plage -r dans la solution de boxxar ne semble pas nécessaire.)J'aime cette variante car je n'ai pas besoin de spécifier deux fois le numéro de ligne de fin. Et j'ai mesuré que l'utilisation
$
n'a pas d'effets néfastes sur les performances.la source
sed -n '16224,16482p' < dump.sql
la source
Rapide et sale:
Ce n'est probablement pas la meilleure façon de le faire, mais cela devrait fonctionner.
BTW: 259 = 16482-16224 + 1.
la source
J'ai écrit un programme Haskell appelé splitter qui fait exactement cela: lire mon article de blog .
Vous pouvez utiliser le programme comme suit:
Et c'est tout ce qu'il y a à faire. Vous aurez besoin de Haskell pour l'installer. Juste:
Et vous avez terminé. J'espère que vous trouverez ce programme utile.
la source
splitter
lit qu'à partir de l'entrée standard? Dans un sens, cela n'a pas d'importance; lacat
commande est superflue qu'elle le fasse ou non. Soit utilisersplitter 16224-16482 < somefile
ou (s'il prend des arguments de nom de fichier)splitter 16224-16482 somefile
.Même nous pouvons le faire pour vérifier en ligne de commande:
Par exemple:
la source
cat
commande dans aucun de ceux-ci;sed
est parfaitement capable de lire des fichiers seul, ou vous pouvez rediriger l'entrée standard d'un fichier.Utilisation de rubis:
la source
J'étais sur le point de publier le truc tête / queue, mais en fait, je déclencherais probablement des emacs. ;-)
ouvrir le nouveau fichier de sortie, ctl-y enregistrer
Voyons ce qui se passe.
la source
J'utiliserais:
FNR contient le numéro d'enregistrement (ligne) de la ligne lue dans le fichier.
la source
Je voulais faire la même chose à partir d'un script en utilisant une variable et je l'ai réalisé en mettant des guillemets autour de la variable $ pour séparer le nom de la variable du p:
Je voulais diviser une liste en dossiers séparés et trouvé la question initiale et répondre à une étape utile. (La commande split n'est pas une option sur l'ancien système d'exploitation sur lequel je dois porter le code).
la source
J'ai écrit un petit script bash que vous pouvez exécuter à partir de votre ligne de commande, tant que vous mettez à jour votre PATH pour inclure son répertoire (ou vous pouvez le placer dans un répertoire qui est déjà contenu dans le PATH).
Utilisation: $ pinch filename start-line end-line
la source
wc
commande, ce qui gaspille la bande passante du disque, en particulier sur les fichiers gigaoctets. À bien des égards, cela est bien documenté, mais c'est aussi une surpuissance technique.Cela pourrait fonctionner pour vous (GNU sed):
ou profiter de bash:
la source
Utilisation de ed:
-s
supprime la sortie de diagnostic; les commandes réelles sont dans une chaîne ici. Plus précisément,16224,16482p
exécute lap
commande (impression) sur la plage d'adresses de ligne souhaitée.la source
Le -n dans les réponses acceptées fonctionne. Voici une autre façon au cas où vous seriez enclin.
Cela fait ce qui suit:
la source
cat file | sed
est mieux écrite commesed file
Puisque nous parlons d'extraire des lignes de texte d'un fichier texte, je donnerai un cas spécial où vous voulez extraire toutes les lignes qui correspondent à un certain modèle.
Imprime la ligne [Données] et le reste. Si vous voulez que le texte de la ligne 1 au motif, vous tapez: sed -n '1, / Data / p' monfichier. De plus, si vous connaissez deux modèles (mieux vaut être unique dans votre texte), les lignes de début et de fin de la plage peuvent être spécifiées avec des correspondances.
la source