append string onde pertence ao arquivo classificado

2

Suponha que eu tenha um arquivo classificado, chamado sorted.txt, assim:

beautiful
easy
fast
functional
handy

Agora, echo fine-grained >> sorted.txt colocará "granulação fina" no final do arquivo, depois de "útil". Existe uma maneira de inseri-lo em ordem, entre "rápido" e "funcional", sem precisar reordenar o arquivo?

    
por Philomath 17.07.2011 / 05:15

4 respostas

3

Embora teoricamente possível, não há uma maneira mágica de fazer isso.

Se você soubesse exatamente qual valor você queria colocar depois de usar sed pesquisa no local e substituir para inserir o novo valor no arquivo, mas, dadas as complexidades da classificação, basicamente se resume a você vai ter que classificá-lo em algum lugar a longo prazo.

echo fine-grained >> sorted.txt
sort sorted.txt > sorted.txt.new && mv sorted.txt{.new,}

Ou com sponge :

{ echo fine-grained ; cat sorted.txt } | sort | sponge sorted.txt

Editar: Gilles fez uma boa sugestão para usar o argumento -m para tipo potencialmente acelerar isso. Do manual:

-m, --merge
 merge already sorted files; do not sort

Isso manteria o processamento desde a entrada até o processamento, ele só precisa varrer os arquivos de entrada e descobrir a relação entre eles.

echo fine-grained | sort -m sorted.txt - | sponge sorted.txt
    
por 17.07.2011 / 08:03
3

Você não pode inserir dados em um arquivo - não há nada na API POSIX para isso. O melhor que você pode fazer é procurar por todos os dados que não se movem, escrever a nova linha e mover todos os dados posteriores para baixo. Isso seria complicado e não seria fácil de fazer sem escrever seu próprio programa.

Se você está feliz em gerar um novo arquivo, o awk pode fazer isso com bastante facilidade:

awk -v newline=fine-grained '
    !inserted && $0 > newline { print newline; inserted=1 }
    1
'

A primeira linha do script imprime a linha que você deseja inserir somente se ainda não tiver feito isso e se a linha de entrada vier depois da linha que você deseja inserir. Também registra que a linha foi inserida.

A segunda linha apenas imprime a linha de entrada (a expressão 1 é verdadeira e a ação padrão é imprimir a linha de entrada, portanto, não precisamos dizer { print } .

    
por 17.07.2011 / 12:14
0

Uma resposta direta à sua pergunta é NÃO, você precisará executar algum tipo de classificação em algum lugar ao longo da linha.

    
por 17.07.2011 / 07:19
0

Você terá que passar por algum tipo de coisa, é só uma questão de quando. Mas o que eu suspeito que você está procurando é um negócio único. Seu método depende de você e existem várias maneiras que podem ser mais rápidas.

Isso faz o trabalho, mas fique à vontade para brincar com outras formas.

echo "$(echo fine-grained | cat - sorted.txt | sort)" > sorted.txt

Desconstruído, começando com o subshell interno para evitar truncar o arquivo antes de lê-lo, concatene a entrada ecoada com o arquivo de disco. Ecoando citou preserva quebras de linha. Então, classifique-o.

Ou o compactado, com a sugestão de sort -m de Giles (e evitando o UUOC).

echo "$(echo fine-grained | sort -m - sorted.txt)" > sorted.txt
    
por 17.07.2011 / 06:08