Reordenar cadenas en Linux

Reordenar cadenas en Linux

¿Cómo puedo cambiar líneas usando la línea de comando?
por ejemplo tengo estas líneas:

    Acct-Status-Type = Start
    User-Name = "37XXXXXXX"
    Event-Timestamp = "Apr 12 2013 15:56:55 AMT"

Necesito cambiar el orden a esto:

    Event-Timestamp = "Apr 12 2013 15:56:55 AMT"
    User-Name = "37XXXXXXX"
    Acct-Status-Type = Start

Necesito hacer esto con un comando, sed, awk, perl o algo así.

Respuesta1

Depende de dónde, con qué frecuencia, por qué, etc. hagas esto, pero no estaría de más ponerlo en un guión.

De todos modos, podrías hacer algo como esto para imprimir en un orden definido. Con este enfoque, también puede optar por imprimir solo unos pocos seleccionados. Por ejemplo, solo 1 y 3:

Un trazador de líneas:

awk -v order=312 \
'/^/{ln[NR]=$0}END{split(order,a,"");
 for(i in a)printf("%s\n",ln[a[i]]);}' \
 sample.txt

O más fácil de leer:

/^/{
    ln[NR] = $0
}
END{
    split(order,a,"");

    for(i in a)
        printf("%s\n",ln[a[i]]);
}

Para la división, puede agregar algún delimitador si tiene más de 9 líneas.

P.ej:

split(order,a,"-");
# and call by:
awk -v order=3-13-21-12-2 ...

O para admitir múltiples:

if (order ~ /-/)       split(order, a, "-"); # order has "-", split
else if (order ~ /\./) split(order, a, "."); # order has ".", split
else if (order ~/:/)   split(order, a, ":"); # order has ":", split
else                   split(order, a, "");  # none presume numbers split all

También puedes optar por hacer coincidir líneas como en:

BEGIN {
    i = 0;
}
/^\s*Acct-Status-Type/ {ln[++i] = $0 }
/^\s*User-Name/ {ln[++i] = $0 }
/^\s*Event-Timestamp/ {ln[++i] = $0 }
END {
    if (order ~ /-/)  split(order, a, "-");
    else if (order ~ /\./) split(order, a, ".");
    else if (order ~/:/) split(order, a, ":");
    else split(order, a, "")
    for (i in a)
        printf("%s\n", ln[a[i]]);
}

Editar:

Para la última muestra, esto probablemente sería mejor. (También actualizó eldividir):

/^\s*Acct-Status-Type/ {ln[1] = $0 }
/^\s*User-Name/ {ln[2] = $0 }
/^\s*Event-Timestamp/ {ln[3] = $0 }
END {
    if (split(order, a, "-|:|,| |\\.") == 1) # Space require quoting of arg.
        split(order, a, "")
    for (i in a)
        printf("%s\n", ln[a[i]]);
}

Respuesta2

Con Python y el nombre del archivo como parámetro de línea de comando del programa:

import sys
with open(sys.argv[1]) as fp:
    for line in fp.readlines()[::-1]:
        sys.stdout.write(line)

o escribiéndolo nuevamente en ese archivo:

import sys
with open(sys.argv[1]) as fp:
    lines = fp.readlines()
with open(sys.argv[1], 'w') as fp:
    for line in lines[::-1]:
        fp.write(line)

o como filtro de stdin a stdout:

lines = sys.stdin.readlines()
for line in lines[::-1]:
    sys.stdout.write(line)

información relacionada