Como concatenar dois arquivos em tempo real e o resultado de referência como novo arquivo?

5

Eu quero concatenar dois arquivos, por exemplo, staticEntries.dic e dynamicEntries.dic. Como os nomes podem mostrar, o conteúdo de staticEntries.dic permanece o mesmo ao longo do tempo (contém palavras comuns), mas, ao contrário, dynamicEntries.dic pode mudar com o tempo (contém abreviações extraídas do DB). No meu editor, desejo fornecer um mydict.dic, que contém o conteúdo de ambos os arquivos. Eu poderia fazer isso via Shell, é claro, mas eu teria que substituir o material dynamicEntries.dic do arquivo mydict.dic antes de concatenar uma nova versão de dynamicEntries.dic para meu mydict.dic resultante. - > Gostaria de criar um arquivo mydict.dic que contenha um comando para concatenar os outros dois arquivos, mas não sei como fazer isso. Como não é executado ou chamado pelo meu editor (eu acho), não posso usar comandos bash.

Posteriormente, um exemplo simples:

Conteúdo de staticEntries.dic

house
dog
horse

Conteúdo de dynamicEntries.dic. Este conteúdo é gerado com base em um banco de dados, por isso muda ao longo do tempo.

EGB38
PD
UH7ZT

Conteúdo perseguido de mydict.dic

house
dog
horse
EGB38
PD
UH7ZT

Se eu fizer essa combinação via shell, tenho um problema se uma nova versão do arquivo dynamicEntries.dic for gerada: como evitar entradas duplicadas no arquivo mydict.dic? Então, eu gostaria de colocar o comando de concatenação em um arquivo e referenciá-lo como um arquivo normal que posso fornecer como arquivo de dicionário ao meu editor. Não sei se isso é possível ou se preciso aplicar outra abordagem.

    
por strauberry 15.09.2013 / 13:33

5 respostas

8

Você poderia escrever um script que fica atrás de um pipe nomeado e despejar o conteúdo de staticEntries.dic e dynamicEntries.dic sempre que for aberto e lido. Anote o tubo que está sendo fechado e termine a saída até que seja aberto novamente.

Mas você teria que deixar esse script em execução em segundo plano e lembrar de iniciá-lo novamente após o logout / login ou a reinicialização.

Mais importante, não é uma tarefa de programação de shell do novato.

Às vezes (normalmente), a solução mais simples é a melhor.

É muito mais simples criar um Makefile que defina mydict.dic como dependente dos outros dois arquivos e lembrar de executar o make para atualizá-lo quando você precisar dele. ou apenas um shell script - a vantagem de um Makefile é que você também pode executá-lo a partir do cron e ele só atualizaria o arquivo de destino (mydict.dic) se qualquer um dos arquivos de origem tivesse mudado.

por exemplo:

#!/usr/bin/make -f

all: mydict.dic

mydict.dic: staticEntries.dic dynamicEntries.dic
        cat staticEntries.dic dynamicEntries.dic > mydict.dic.tmp
        mv mydict.dic.tmp mydict.dic

as linhas com cat e mv começam com uma tabulação, não com espaços.

O arquivo concatenado é criado como um arquivo temporário primeiro e depois movido para o lugar, portanto, a substituição do antigo pelo novo é uma operação atômica. isso é feito para que, sempre que você usar o arquivo, você tenha a versão antiga completa ou a nova versão completa, mas nunca uma versão parcial do novo.

se qualquer um dos arquivos .dic de origem estiver em um diretório diferente, você precisará especificar os nomes completos dos arquivos para os arquivos.

    
por 15.09.2013 / 13:59
4

Eu apenas executaria um pequeno cronjob que re-concatena o arquivo se o dicionário dinâmico tiver sido modificado. Primeiro, escreva um pequeno script que observe as alterações no arquivo:

#!/usr/bin/env bash
while true; do
  inotifywait -e modify path/to/dynamicEntries.dic
  sort path/to/dynamicEntries.dic /path/to/staticEntries.dic | 
    uniq > mydict.dic.tmp
  sleep 1
done

Agora, salve esse script como dict.sh ou algo assim, torne-o executável (chmod a+x dict.sh ) e crie um crontab que inicie o script na reinicialização. Execute crontab -e e cole nesta linha:

@reboot /path/to/dict.sh

Agora, o dicionário deve ser atualizado automaticamente toda vez que o dinâmico mudar e você não precisar executar nada manualmente.

    
por 15.09.2013 / 17:27
3

Concatenar arquivos no shell é fácil:

cat staticEntries.dic dynamicEntries.dic

Isso imprimirá o conteúdo desses dois arquivos em stdout . Se você quiser redirecionar o resultado para um novo arquivo, faça:

cat staticEntries.dic dynamicEntries.dic > mydict.dic

Mas isso provavelmente não é o que você está procurando ...? Eu tenho que dizer, eu realmente não entendo o problema que você está tentando resolver.

    
por 15.09.2013 / 13:41
2

Se você quiser que um arquivo seja concatenado dinamicamente toda vez que acessá-lo, provavelmente terá que recorrer à criação de um sistema de arquivos FUSE ou mecanismo semelhante para ele.

Como alternativa, você pode mapeá-los usando dispositivos de loop / mapeador de dispositivos, mas duvido que isso funcione corretamente. Em particular, o mapeamento teria que ser atualizado toda vez que os arquivos mudassem.

Se qualquer programa que estiver lendo este arquivo for de código aberto, pode ser mais fácil corrigi-lo para ler os dois arquivos em primeiro lugar. Ou embrulhe-o em um script de shell para que o arquivo dic seja concatenado toda vez que você iniciar seu programa.

    
por 15.09.2013 / 13:53
1

Você pode mudar a maneira como chama seu editor. Suponha que você esteja usando vi , você pode criar um script de shell editmydictionary.sh :

cat staticEntries.dic dynamicEntries.dic > mydict.dic.tmp
vi mydict.dic.tmp

então sempre que você executar editmydictionary.sh , você está editando a versão mais recente dos 2 arquivos.

    
por 15.09.2013 / 21:57