enfoque extraño:

enfoque extraño:

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 sedenfoque:

$ sed -nE '1s/.{11}(.{8}).*/\1/p; 3s/.{3}(.{4}).*/\1/p' file  
Ethernet
t6 a

Explicación

Suprime la -nsalida normal (lo normal es imprimir cada línea de entrada) para que solo imprima cuando se le indique. El -Ehabilita expresiones regulares extendidas.

El sedscript tiene dos comandos, ambos usando el operador de sustitución ( s/original/replacement/). Solo se 1s/.{11}(.{8}).*/\1/pejecutará en la primera línea (eso es lo que 1shace) 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 \2etc.). Finalmente, al pfinal ( 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 -ea 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 1y 3, si entonces, ejecute la sustitución; de lo contrario, omítala. Por lo tanto, printsolo 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í, -asignifica "dividir cada línea de entrada en el carácter dado por -Fy 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 NRpara 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

información relacionada