web-dev-qa-db-fra.com

Awk - Sortie la deuxième ligne d'un certain nombre de fichiers .dat à un fichier

J'ai plusieurs fichiers quelque chose comme: (en réalité j'ai 80)

file1.dat

2 5

6 9

7 1

file2.dat

3 7

8 4

1 3

Je veux retrouver avec un fichier contenant toutes les deuxième lignes. c'est à dire.

sortie.dat

6 9

8 4

Ce que j'ai jusqu'à présent, des boucles les noms de fichiers mais écrit ensuite le fichier avant de cela. par exemple. la sortie des fichiers ci-dessus serait juste être

8 4

mon script shell ressemble à ceci:

post.sh

TEND = 80

TINDX = 0

while [ $TINDX - lt $TEND]; do

awk '{ print NR==2 "input-$TINDX.dat > output.dat

TINDX = $((TINDX+1))

done
9
Rowland

Supprimer while boucle et utilisez l'expansion de la corset de coquille et aussi FNR, une variable intégrée awk:

awk 'FNR==2{print $0 > "output.dat"}' file{1..80}.dat
17
jimmij

sed serait suffisant:

sed -sn 2p file{1..80}.dat > output.dat

-s Option est nécessaire pour imprimer 2nd ligne à partir de chaque fichier, sinon une 2ème ligne de premier fichier sera imprimée.

7
aragaer

Qu'en est-il de ... head -n 2 input.dat | tail -n 1 | awk ...

6
HarveyP

l'Aragaer's sed _ solution est le plus gentil, oui. Mais moi depuis que je profite d'un peu de head|tail couper, avoir un head|tail Solution prenant en charge plusieurs fichiers, pas seulement un seul input.dat. En utilisant une boucle pour une boucle, au lieu de transmettre une liste de fichiers à SED, facilite également la tâche de faire autre chose avec le fichier avant/après avoir extrait la deuxième ligne avec SED.

# empty output.dat first
rm output.dat

# have a one-liner
for file in *.dat; do head -2 $file | tail -1 >> output.dat; done 

Version multi-lignes copieuse-commentée:

NB: Le code ci-dessous fonctionnera. Nous sommes libres de mettre un cheviche après un |, &&, ou ||, et poursuivez notre commande sur la ligne suivante; Nous pouvons même mettre des commentaires entre les deux. J'ai passé années Ne sachant pas cela (et ne pas y voir vraiment nulle part). Ce style est moins utile à l'invite interactive, mais nettoie les fichiers de script sans fin.

# empty output.dat first
rm output.dat

for file in *.dat; do
    # file -> lines 1 and 2 of file
    head -2 $file |
    # lines 1 and 2 of file -> line 2 of file >> appended to output.dat
    tail -1 >> output.dat
done
2
Esteis

Il y a évidemment beaucoup de façons de faire cela - je pense que j'aime @ Aragaer's SED répond le mieux .

Voici celui qui utilise purement bash Bascules et n'a pas besoin de fourchette d'utilitaires externes:

for f in file{1..80}.dat; do
    { read && read && printf "%s\n" "$REPLY"; } < "$f"
done > output.dat
0
Digital Trauma

Pour l'utilisation de l'efficacité de awk et sed dans les réponses ici sur plusieurs fichiers, mieux utiliser nextfile instruction pour ignorer les lignes non désirées dans awk.

awk 'FNR==2{ print >"output.dat"; nextfile}' infile{1..80}.dat

et avec sed, nous pouvons sortir lors du traitement de 3rd ligne et sed _ traitera le fichier suivant.

sed -sn '2p;3q' infile{1..80}.dat > output.dat
0
αғsнιη