Je souhaite imprimer les lignes impaires et paires à partir des fichiers.
J'ai trouvé ce script shell qui utilise l'écho.
#!/bin/bash
# Write a shell script that, given a file name as the argument will write
# the even numbered line to a file with name evenfile and odd numbered lines
# in a text file called oddfile.
# -------------------------------------------------------------------------
# Copyright (c) 2001 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
file=$1
counter=0
eout="evenfile.$$" # even file name
oout="oddfile.$$" # odd file name
if [ $# -eq 0 ]
then
echo "$(basename $0) file"
exit 1
fi
if [ ! -f $file ]
then
echo "$file not a file"
exit 2
fi
while read line
do
# find out odd or even line number
isEvenNo=$( expr $counter % 2 )
if [ $isEvenNo -ne 0 ]
then
# even match
echo $line >> $eout
else
# odd match
echo $line >> $oout
fi
# increase counter by 1
(( counter ++ ))
done < $file
echo "Even file - $eout"
echo "Odd file - $oout"
Mais n'y a-t-il pas moyen de le faire en une seule ligne?
Oui, utilisez awk, j'ai lu.
Lignes paires:
awk 'NR % 2' filename
lignes impaires:
awk 'NR % 2 == 1' filename
Mais ça ne marche pas pour moi. Les deux produisent la même sortie, selon diff. Par rapport au fichier d'origine, ils sont tous deux en fait deux fois moins longs et contiennent tous les deux des lignes impaires. Est-ce que je fais quelque chose de mal?
text-processing
sed
awk
ixtmixilix
la source
la source
NR % 2 == 0
, sinon il est équivalent au second.Réponses:
Comme vous l'avez demandé «en une seule ligne»:
Notez que la plupart du code est dû à votre choix de nom de fichier de sortie de fantaisie. Sinon, le code suivant serait suffisant pour mettre des lignes impaires dans "ligne-1" et des lignes paires dans "ligne-0":
la source
Je préfère être compatible POSIX, dans la mesure du possible, j'ai donc pensé publier cette méthode alternative. Je les utilise souvent pour modifier le texte, avant les
xargs
pipelines.Imprimer des lignes paires,
Imprimer des lignes impaires,
Bien que j'utilise souvent
awk
, c'est exagéré pour ce type de tâche.la source
C'est facile:
imprimera les lignes paires à partir du nom de fichier
imprime des lignes impaires.
la source
awk
, personnellement je l'utilise très souvent. Je n'ai jamais dit que rien n'était «pas POSIX»awk
, je faisais référence auxsed
options de la réponse . Spécifiquement l'~
opérateur, c'est une extension GNU, qui est toujours acceptable pour beaucoup de gens. En ce qui concerne «l'utilisation d'AWK, I personally believe using
extrêmement awk» pour cette tâche simple, c'est exagéré. Donc, le +1 était pour avoir terminé la tâche avecsed
, un utilitaire plus léger queawk
.Pour les nombres pairs, le code doit être
& pour les nombres impairs
la source
gawk 'FS=",";NF%2==0' file.csv
.Vous pouvez le faire avec une seule
sed
invocation, pas besoin de lire le fichier deux fois:ou, si vous préférez sur une seule ligne:
Notez que ceux-ci ne donneront pas le résultat attendu si un fichier ne contient qu'une seule ligne (la ligne sera
w
écrite aueven
lieu deodd
car la premièren
n'est pas exécutée). Pour éviter cela, ajoutez une condition:Comment ça fonctionne ? Eh bien, il utilise trois
sed
commandes:n
- si ce n'est pas sur la dernière ligne, imprimez l'espace de motif versstdout
(qui est redirigé vers le fichierodd
), remplacez-le par la ligne suivante (alors maintenant il traite une ligne paire) et continuez à exécuter les commandes restantesw
- ajoutez l'espace de motif à classereven
d
- supprimez l'espace de motif actuel et redémarrez le cycle - l'effet secondaire est quesed
cela n'imprimera jamais automatiquement l'espace de motif car il n'atteint jamais la fin du scriptEn d'autres termes,
n
est exécuté uniquement sur les lignes impaires etw
etd
n'est exécuté que sur les lignes paires.sed
ne parvient jamais à l'impression automatique à moins que, comme je l'ai dit, l'entrée se compose d'une seule ligne.la source
Essaye ça:
la source
J'irais avec
perl
parce que j'aimeperl
:Utilise le fait d'
-p
imprimer implicitement, pour reproduire lesed
fonctionnement - et nous utilisonsselect
pour choisir le descripteur de fichier dans lequel il écrit.la source