Quiero imprimir las líneas impares y pares de los archivos.
Encontré este script de shell que hace uso de echo.
#!/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"
¿Pero no hay una manera de hacerlo en una línea?
Sí, usa awk, leí.
Líneas pares:
awk 'NR % 2' filename
líneas impares:
awk 'NR % 2 == 1' filename
Pero no me funciona. Ambos producen la misma salida, según diff. En comparación con el archivo original, ambos tienen la mitad de longitud y ambos contienen las líneas impares. ¿Estoy haciendo algo mal?
text-processing
sed
awk
ixtmixilix
fuente
fuente
NR % 2 == 0
, de lo contrario es equivalente al segundo.Respuestas:
Como preguntaste "en una línea":
Tenga en cuenta que la mayor parte del código se debe a su elección de nombre de archivo de salida elegante. De lo contrario, el siguiente código sería suficiente para poner líneas impares en "línea-1" y líneas pares en "línea-0":
fuente
Prefiero ser compatible con POSIX, siempre que sea posible, así que pensé en publicar este método alternativo. A menudo los uso para alterar el texto, antes de las
xargs
tuberías.Imprimir incluso líneas numeradas,
Imprimir líneas numeradas impares,
Aunque a menudo lo uso
awk
, es excesivo para este tipo de tarea.fuente
Eso es fácil:
imprimirá líneas pares del nombre del archivo
imprimirá líneas impares.
fuente
awk
, personalmente lo uso con mucha frecuencia. Nunca dije que se tratara de 'No POSIX'awk
, me refería a lassed
opciones de respuesta . Específicamente el~
operador, es una extensión GNU, que todavía es aceptable para muchas personas. Respecto a 'usar AWK, I personally believe using
extrañamente awk' para esta tarea simple es excesivo. Entonces, el +1 fue para completar la tarea consed
una utilidad más ligera queawk
.Para números pares, el código debe ser
y para números impares
fuente
gawk 'FS=",";NF%2==0' file.csv
.Puede hacerlo con una sola
sed
invocación, no es necesario leer el archivo dos veces:o, si lo prefiere en una línea:
Tenga en cuenta que estos no darán el resultado esperado si un archivo contiene solo una línea (la línea se repetirá
w
eneven
lugar deodd
que la primeran
no se ejecute). Para evitar eso, agregue una condición:Cómo funciona ? Bueno, utiliza tres
sed
comandos:n
si no está en la última línea, imprima el espacio del patrónstdout
(que se redirige al archivoodd
), reemplácelo con la siguiente línea (por lo que ahora está procesando una línea uniforme) y continúe ejecutando los comandos restantesw
: agregue el espacio de patrón para archivareven
d
: elimine el espacio de patrón actual y reinicie el ciclo; el efecto secundario de esto es quesed
nunca imprimirá automáticamente el espacio de patrón ya que nunca llega al final del scriptEn otras palabras,
n
se ejecuta sólo en líneas pares ew
yd
son ejecutados sólo en líneas pares.sed
nunca llega a la impresión automática a menos que, como dije, la entrada consista en una sola línea.fuente
Prueba esto:
fuente
Yo iría
perl
porque me gustaperl
:Utiliza el hecho de que
-p
imprime implícitamente, para replicar cómosed
funciona, y usamosselect
para elegir qué identificador de archivo en el que escribe.fuente