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:
find
pour produire une liste de fichiers portant un nom commençant par la chaîne “year”. sed
pour extraire le numéro de ligne souhaité du nom du fichier 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}