
Como posso alterar as linhas usando a linha de comando?
por exemplo, eu tenho estas linhas:
Acct-Status-Type = Start
User-Name = "37XXXXXXX"
Event-Timestamp = "Apr 12 2013 15:56:55 AMT"
Preciso mudar a ordem para isso:
Event-Timestamp = "Apr 12 2013 15:56:55 AMT"
User-Name = "37XXXXXXX"
Acct-Status-Type = Start
Preciso fazer isso com um comando, sed, awk, perl ou algo parecido.
Responder1
Depende de onde, com que frequência, por que você faz isso, mas não faria mal nenhum colocá-lo em um script.
De qualquer forma, você poderia fazer algo assim para imprimir em ordem definida. Com esta abordagem, você também pode optar por imprimir apenas alguns selecionados. Por exemplo, apenas 1 e 3:
Um forro:
awk -v order=312 \
'/^/{ln[NR]=$0}END{split(order,a,"");
for(i in a)printf("%s\n",ln[a[i]]);}' \
sample.txt
Ou mais fácil de ler:
/^/{
ln[NR] = $0
}
END{
split(order,a,"");
for(i in a)
printf("%s\n",ln[a[i]]);
}
Para a divisão, você pode adicionar algum delimitador se tiver mais de 9 linhas.
Por exemplo:
split(order,a,"-");
# and call by:
awk -v order=3-13-21-12-2 ...
Ou para oferecer suporte a vários:
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
Você também pode optar por combinar linhas como em:
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 a última amostra, isso provavelmente seria melhor. (Também atualizou odividir):
/^\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]]);
}
Responder2
Com Python e o nome do arquivo como parâmetro de linha de comando do programa:
import sys
with open(sys.argv[1]) as fp:
for line in fp.readlines()[::-1]:
sys.stdout.write(line)
ou gravá-lo de volta nesse arquivo:
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)
ou como um filtro de stdin para stdout:
lines = sys.stdin.readlines()
for line in lines[::-1]:
sys.stdout.write(line)