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
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
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.
Qu'en est-il de ... head -n 2 input.dat | tail -n 1 | awk
...
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
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
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