Comment lire la ligne N du fichier et l’imprimer dans un nouveau fichier?

J’ai un dossier appelé foo. Foo a d’autres dossiers pouvant contenir des sous-dossiers et des fichiers texte. Je veux trouver tous les fichiers qui commencent par l’année du nom et lire sa Nième ligne et l’imprimer dans un nouveau fichier. Par exemple, foo a un fichier appelé year1 et les sous-dossiers ont des fichiers appelés year2, year3, etc.

Je n’ai pas vraiment compris comment faire une boucle pour un fichier.

Jusqu’à présent j’ai:

#!/bin/bash for year* in ~/foo do Here I sortinged writing some code using the sed command but I can't think of something else. done 

Je reçois également un message dans le terminal qui dit «année *» et non un identifiant valide. Des idées?

Sed peut vous aider.

Rappelez-vous que sed traitera normalement toutes les lignes d’un fichier ET imprimera chaque ligne du fichier.

Vous pouvez désactiver cette fonctionnalité et ne plus imprimer que les lignes d’intérêt en faisant correspondre un motif ou un numéro de ligne.

Donc, pour imprimer la 2ème ligne du fichier 2, vous pouvez dire

 sed -n '2p' file2 > newFile2 

Pour imprimer la deuxième ligne puis arrêter le traitement, ajoutez la commande q (pour quitter) (vous avez également besoin d’accolades pour regrouper les deux commandes), c.-à-d.

 sed -n '2{p;q;}' file2 > newFile2 

(si vous traitez des fichiers volumineux, cela peut vous faire gagner du temps).

Pour rendre cela plus général, vous pouvez changer le nombre en une variable qui contiendra un nombre, à savoir

  lineNo=3 sed -n "${lineNo}{p;q;}" file3 > newFile3 

Si vous voulez que toutes vos lignes tranchées soient placées dans un fichier, utilisez les shells “append-redirection”, c.-à-d.

  for lineNo in 1 2 3 4 5 ; do sed -n "${lineNo}{p;q;}" file${lineNo} >> aggregateFile done 

Les autres messages, avec l’utilisation des résultats de find ... pour conduire votre liste de fichiers, sont une excellente approche.

J’espère que ça aide.

Voici une façon de le faire:

 awk "NR==$YEAR" $file 

Utilisez find pour localiser les fichiers souhaités, puis sed pour extraire ce que vous voulez:

 find foo -type f -name year* | while read file; do line=$(echo $file | sed 's/.*year\([0-9]*\)$/\1/') sed -n -e "$line {p; q}" $file done 

Cette approche:

  • Utilisez find pour produire une liste de fichiers portant un nom commençant par la chaîne “year”.
  • Pipe la liste de fichiers dans une boucle while pour éviter les longues lignes de commande
  • Utilise sed pour extraire le numéro de ligne souhaité du nom du fichier
  • Utilise sed pour imprimer uniquement la ligne désirée, puis quitte immédiatement. (Vous pouvez laisser de côté le q et écrire simplement ${line}p qui fonctionnerait mais être potentiellement moins efficace de $file is big. De plus, q peut ne pas être entièrement pris en charge sur toutes les versions de sed .)

Il ne fonctionnera pas correctement pour les fichiers avec des espaces dans leurs noms cependant.

Le meilleur moyen fonctionne toujours, à condition de fournir 2 arguments:

 $ touch myfile $ touch mycommand $ chmod +x mycommand $ touch yearfiles $ find / -type f -name year* >> yearfiles $ nano mycommand $ touch foo 

Tapez ceci:

 #/bin/bash head -n $1 $2 >> myfile less -n 1 myfile >> foo 

Utilisez ^X , y et entrez pour enregistrer. Puis lancez ma commande:

 $ ./mycommand 2 yearfiles $ cat foo year2 

En présumant vos fichiers de l’ year sont:

 year1, year2, year3 

De plus, maintenant que vous avez la configuration, il vous suffit d’utiliser $ ./mycommand LINENUMBER FILENAME partir de maintenant.

Votre tâche comporte deux sous-tâches: Recherchez le nom de tous les fichiers d’année, puis extrayez la Nième ligne. Considérons le script suivant:

 for file in `find foo -name 'year*'`; do YEAR=`echo $file | sed -e 's/.*year\([0-9]*\)$/\1/'` head -n $YEAR $file | tail -n 1 done 

L’appel de recherche trouve les fichiers correspondants pour vous dans le répertoire foo. La deuxième ligne extrait uniquement les chiffres à la fin du nom de fichier du nom de fichier. La troisième ligne extrait ensuite les N premières lignes du fichier, ne conservant que la dernière des N premières lignes (lire: uniquement la Nième ligne).

 1.time head -5 emp.lst tail -1 It has taken time for execution is real 0m0.004s user 0m0.001s sys 0m0.001s or 2.awk 'NR==5' emp.lst It has taken time for execution is real 0m0.003s user 0m0.000s sys 0m0.002s or 3.sed -n '5p' emp.lst It has taken time for execution is real 0m0.001s user 0m0.000s sys 0m0.001s or 4.using some cute sortingck we can get this with cut command cut -d “ “ -f 5 emp.lst # after -d press enter ,it means delimiter is newline It has taken time for execution is real 0m0.001s 

Voici

 sed ${index}'q;d' ${input_file} > ${output_file}