Tengo un archivo con datos que guardo. Ahora me gustaría imprimir mis resultados en un archivo nuevo.
Por ejemplo, tomemos este ejemplo randomlog.log
:
Link encap:Ethernet HWaddr 08:00:00:00:00:67
inet addr:10.10.10.10 Bcast:10.10.10.10 Mask:255.255.255.0
inet6 addr: fe80::casf:sdfg:23ra:dg12/64 Scope:Link
¿Cómo puedo tomar solo datos del carácter 12 al 20 de la primera línea y luego del 4 al 8 de la tercera línea? La salida se vería así:
Ethernet
t6 ad
es posible? Quiero establecer la línea y desde la posición a esta posición.
Respuesta1
He aquí un sed
enfoque:
$ sed -nE '1s/.{11}(.{8}).*/\1/p; 3s/.{3}(.{4}).*/\1/p' file
Ethernet
t6 a
Explicación
Suprime la -n
salida normal (lo normal es imprimir cada línea de entrada) para que solo imprima cuando se le indique. El -E
habilita expresiones regulares extendidas.
El sed
script tiene dos comandos, ambos usando el operador de sustitución ( s/original/replacement/
). Solo se 1s/.{11}(.{8}).*/\1/p
ejecutará en la primera línea (eso es lo que 1s
hace) y coincidirá con los primeros 11 caracteres de la línea ( .{11}
), luegocapturaslos siguientes 8 ( (.{8})
, los paréntesis son un "grupo de captura") y luego todo lo demás hasta el final de la línea ( .*
). Todo esto se reemplaza con lo que haya en el grupo de captura ( \1
; si hubiera un segundo grupo de captura, sería \2
etc.). Finalmente, al p
final ( s/foo/bar/p
) hace que la línea se imprima después de que se haya realizado la sustitución. Esto da como resultado que solo se generen los 8 caracteres de destino.
El segundo comando tiene la misma idea general excepto que solo se ejecutará en la tercera línea ( 3s
) y mantendrá los 4 caracteres a partir de la cuarta.
También puedes hacer lo mismo con perl
:
$ perl -ne 'if($.==1){s/.{11}(.{8}).*/\1/}
elsif($.==3){s/.{3}(.{4}).*/\1/}
else{next}; print; ' file
Ethernet
t6 a
Explicación
Significa -ne
"leer el archivo de entrada línea por línea y aplicar el script dado por -e
a cada línea. El script tiene la misma idea básica que antes. La $.
variable contiene el número de línea actual, por lo que verificamos si el número de línea es o 1
y 3
, si entonces, ejecute la sustitución; de lo contrario, omítala. Por lo tanto, print
solo se ejecutará para esas dos líneas, ya que todas las demás se omitirán.
Por supuesto, esto es Perl, así queTIMTOWTDI:
$ perl -F"" -lane '$. == 1 && print @F[11..19]; $.==3 && print @F[3..6]' file
Ethernet
t6 a
Explicación
Aquí, -a
significa "dividir cada línea de entrada en el carácter dado por -F
y guardar como matriz @F
. Dado que el carácter dado está vacío, esto guardará cada carácter de la línea de entrada como un elemento en @F
. Luego, imprimimos los elementos 11-19 ( las matrices comienzan a contar en 0
) para la primera línea y 3-7 para la tercera.
Respuesta2
enfoque extraño:
$ awk 'NR==1{print substr($0,12,8)};NR==3{print substr($0,4,4)}' input.txt
Ethernet
t6 a
Se utiliza NR
para determinar el número de línea (en terminología awk, registro) y, en consecuencia, imprimir la subcadena de la línea. substr()
la función está en formato
substr(string,starting position,how much offset)
Pitón
$ python -c 'import sys
> for index,line in enumerate(sys.stdin,1):
> if index == 1:
> print line[11:19]
> if index == 3:
> print line[3:7]' < input.txt
Ethernet
t6 a
Esto utiliza <
el operador de shell para redirigir el flujo de entrada al proceso de Python desde el archivo de entrada. Tenga en cuenta que las cadenas en Python tienen un índice de 0, por lo que debe cambiar los números de caracteres deseados en 1.
forma de concha portátil
Esto funciona en ksh
, dash
, bash
. Se basa únicamente en utilidades de shell, nada externo.
#!/bin/sh
rsubstr(){
i=0;
while [ $i -lt $2 ];
do
rmcount="${rmcount}?"
i=$(($i+1))
done;
echo "${1#$rmcount}"
}
lsubstr(){
printf "%.${2}s\n" "$1"
}
line_handler(){
case $2 in
1) lsubstr "$(rsubstr "$1" 11)" 8 ;;
3) lsubstr "$(rsubstr "$1" 3)" 5 ;;
esac
}
readlines(){
line_count=1
while IFS= read -r line;
do
line_handler "$line" "$line_count"
line_count=$(($line_count+1))
done < $1
}
readlines "$1"
Y funciona así:
$ ./get_line_substrings.sh input.txt
Ethernet
t6 ad