UNIX Comando para classificar o arquivo com base em palavras delimitadas por palavra

1

Eu tenho um arquivo que tem linhas file.txt assim:

www.site.com/230207|Sophie Rundle title: Episodes|5irko3ke
www.site.com/228264|Camilla Luddington title: Balifornication|5423234
www.site.com/228592|Sarah Power title: Californication|23423423
www.site.com/229022|Ali Cobrin title: American Reunion|tgkmktgkmtg
www.site.com/190074|Eva Green title: The Dreamers|rfrrfrf

Eu quero que ele seja classificado em fileSorted.txt em ordem alfabética pela palavra que vem depois de "title", então o resultado seria:

www.site.com/229022|Ali Cobrin title: American Reunion|tgkmktgkmtg
www.site.com/228592|Sarah Power title: Balifornication|23423423
www.site.com/228264|Camilla Luddington title: Californication|5423234
www.site.com/230207|Sophie Rundle title: Episodes|5irko3ke
www.site.com/190074|Eva Green title: The Dreamers|rfrrfrf

Eu sei que temos que usar o comando sort , então eu tentei:

sort --field-separator='title:'  --key=1  file.txt > fileSorted.txt

mas eu tenho esse resultado:

sort: multi-character tab ‘title:’

Eu tentei pesquisar pela internet, mas não consegui "encontrar uma solução". Como posso classificar o arquivo da maneira que desejo como explicado acima? O arquivo tem 100 mil linhas, portanto, o desempenho é importante.

    
por George Chalhoub 20.12.2015 / 18:06

4 respostas

0

Eu encontrei uma maneira de fazer isso de maneira fácil e eficiente usando uma linha no bash:

sort --field-separator=':'  --key=3  file.txt > fileSorted.txt
    
por 26.12.2015 / 15:01
2

Talvez simplista demais (não funcionará corretamente se houver campos em que o nome do autor tenha um caractere ":"), mas você pode simplesmente classificar no campo ":" com o comando

sort -t: -k2 del.file
    
por 20.12.2015 / 21:30
1

Use sed para alterar temporariamente a sequência. Este exemplo faz com que seja um controle A :

#!/bin/sh
SEP=$(echo x|tr x '
www.site.com/229022|Ali Cobrin title: American Reunion|tgkmktgkmtg
www.site.com/228264|Camilla Luddington title: Balifornication|5423234
www.site.com/228592|Sarah Power title: Californication|23423423
www.site.com/230207|Sophie Rundle title: Episodes|5irko3ke
www.site.com/190074|Eva Green title: The Dreamers|rfrrfrf 
1') sed -e "s/title:/$SEP/" file.txt | \ sort -k2 -t "$SEP" --key=1 |\ sed -e "s/$SEP/title:/" > fileSorted.txt

#!/bin/sh
SEP=$(echo x|tr x '
www.site.com/229022|Ali Cobrin title: American Reunion|tgkmktgkmtg
www.site.com/228264|Camilla Luddington title: Balifornication|5423234
www.site.com/228592|Sarah Power title: Californication|23423423
www.site.com/230207|Sophie Rundle title: Episodes|5irko3ke
www.site.com/190074|Eva Green title: The Dreamers|rfrrfrf 
1') sed -e "s/title:/$SEP/" file.txt | \ sort -k2 -t "$SEP" --key=1 |\ sed -e "s/$SEP/title:/" > fileSorted.txt

No seu exemplo, você estava classificando desde o começo da linha. Com base nos comentários, você pretendia classificar pelos dados iniciados após a sequência "title:" , exigindo a opção -k2 . (Eu mudei a opção de separação para POSIX também).

Para referência, POSIX:

por 20.12.2015 / 18:35
1

Você não disse quais ferramentas você queria usar, e é sempre bom ter opções, então aqui está uma solução perl para acompanhar a solução sed / sort de Thomas.

$ cat file.txt
www.site.com/230207|Sophie Rundle title: Episodes|5irko3ke
www.site.com/228264|Camilla Luddington title: Balifornication|5423234
www.site.com/228592|Sarah Power title: Californication|23423423
www.site.com/229022|Ali Cobrin title: American Reunion|tgkmktgkmtg
www.site.com/190074|Eva Green title: The Dreamers|rfrrfrf
$ cat sortfile.pl
#!/usr/bin/perl --

use strict;
use warnings;

my @lines;

while (<>)
{
    push @lines, "$1\x00$_" if /title: (.*)/;
}

foreach (sort @lines)
{
    s/.*\x00//;

    print $_;
}
$ ./sortfile.pl file.txt
www.site.com/229022|Ali Cobrin title: American Reunion|tgkmktgkmtg
www.site.com/228264|Camilla Luddington title: Balifornication|5423234
www.site.com/228592|Sarah Power title: Californication|23423423
www.site.com/230207|Sophie Rundle title: Episodes|5irko3ke
www.site.com/190074|Eva Green title: The Dreamers|rfrrfrf

O conceito é copiar o texto que você deseja classificar para a frente, classificar e remover o texto copiado. As partes principais são:

while (<>)
{
    push @lines, "$1\x00$_" if /title: (.*)/;
}

Isso faz um loop em todas as linhas de todos os arquivos nomeados na linha de comando (ou na entrada padrão, se não houver nenhum) e lê cada linha em $_ . O if no final da terceira linha certifica-se de que a linha se parece com uma que queremos processar e salva tudo depois de title: in $1 . O push , em seguida, envia uma linha para @lines , que contém o título (de $1 ), um separador que não deve ocorrer em um título (ASCII nul ) e o restante da linha. Quando esse loop é feito, todas as linhas estão em @lines com o título copiado para a frente.

foreach (sort @lines)
{
    s/.*\x00//;

    print $_;
}

Isso faz um loop sobre todas as linhas acumuladas em @lines depois de classificá-las. Porque o título foi copiado para o início de cada linha, as linhas são classificadas por título. O s/.*\x00//; retira o título e o separador ASCII nul , restaurando a linha para a forma original. O print , em seguida, imprime toda a linha (restaurada).

    
por 20.12.2015 / 20:40