Eu tenho este arquivo de texto:
714
01:11:22,267 --> 01:11:27,731
Auch wenn noch viele Generationen auf einen Wechsel hoffen,
Even if it takes many generations hoping for a change,
715
01:11:27,732 --> 01:11:31,920
werde ich mein Bestes geben
und hoffe, dass andere das gleiche tun.
I'm giving mine, I'm doing my best
hoping the other will do the same
716
01:11:31,921 --> 01:11:36,278
Wir haben eine harte Arbeit vor uns,
um den Lauf der Dinge zu ändern.
it's going to be hard work
for things to turn around.
717
01:11:36,879 --> 01:11:42,881
Wenn man die Zentren künstlicher Besamung,
die Zuchtlaboratorien und die modernen Kuhställe besichtigt,
When visiting artificial insemination centers,
the selection center, modern stables,
...
e gostaria de analisá-lo para que apenas as linhas não inglesas fiquem
Isso é possível?
Respostas:
Existe uma maneira difícil e muito mais fácil. A maneira mais difícil é usar a análise de linguagem natural para dar uma probabilidade de que uma determinada linha esteja em inglês e descartar essas linhas.
A maneira mais fácil é pegar uma lista de palavras de parada em inglês e excluir linhas que contêm elementos dessa lista. Se você quisesse diminuir a chance de categorizar incorretamente uma linha, também poderia procurar a presença de palavras de parada em alemão nas linhas que você não consegue rejeitar para verificar se elas provavelmente são alemãs.
Aqui está um script muito rápido e sujo para usar a lista de palavras de parada vinculada para fazer a filtragem:
e a saída:
Uma versão um pouco mais completa deve ignorar várias pontuações, como
,.
no apóstrofo inglês,'
quando dentro de uma palavra. É possível obter uma precisão ainda maior procurando pontos de código que nunca ocorrem em inglês (por exemplo«ßü
), mas que são deixados como um exercício para o leitor.fonte
Na sua amostra, isso funcionaria:
Detalhes
RS=
. Define o separador de registros . Um valor vazio é um caso especial que significa que um registro é um parágrafo (sequência de linhas delimitadas por linhas vazias).-F '\n'
: define o separador de campos (os campos em cada registro são linhas).OFS='\n'
: define o separador do campo de saída.Para cada registro (parágrafo):
NF=1+NF/2
(ouNF=2
(as duas primeiras linhas)+ (NF-2)/2
(metade das linhas restantes)): altere o número de campos para excluir os ingleses.printf "%s", $0 RT
: imprime o registro seguido pelo terminador do registro (para restaurar a mesma quantidade de espaçamento entre parágrafos). Para ver o que o código acima está fazendo, é útil se você adicionar algumas instruções de impressão ao mix. Algo assim:Isso assume finais de linha Unix. Se o arquivo estiver no formato MSDOS, como é comum nos arquivos de legenda, você precisará pré-processá-lo com
d2u
oudos2unix
.fonte
NF-=NF/2-1
. Você está calculando, digamos,NF=4
para o primeiro registro, 714. Então você obtém os valoresNF=4
eNF/2-1=1
, em seguida, subtrai o valor1
deNF
deixar você com você3
? Em seguida, imprimindo os primeiros3
"campos" do registro, eliminando a quarta linha?A peça chave para esse tipo de abordagem é ter acesso a um bom banco de dados de palavras em inglês. Existe esse arquivo no meu sistema,
/usr/share/dict/words
que possui muitas palavras, mas outras fontes podem ser usadas.Abordagem
Minha abordagem geral seria usar
grep
assim:Onde está o seu exemplo de saída
sample.txt
.Nos meus testes limitados, o tamanho do
words
dicionário pareceu atolargrep
. Minha versão tem mais de 400k linhas. Então comecei a fazer algo assim para dividir um pouco:Execuções de amostra (10k)
O arquivo é executado usando as primeiras 10 mil palavras do "dicionário".
NOTA: Essa abordagem foi executada em ~ 1,5 segundos, no meu laptop i5.
Parece ser uma abordagem viável. No entanto, quando aumentei até 100k linhas, o processo demorou muito tempo a abortar antes de terminar, para que você pudesse dividir o
words
dicionário em vários arquivos.NOTA: Quando eu recuei em 50k linhas, demorou 32 segundos.
Mergulho mais profundo (50 mil linhas)
Quando comecei a expandir o dicionário até 50k, deparei-me com o problema que tinha, sobreponho-me entre os idiomas.
Analisando o problema
Uma coisa boa dessa abordagem é que você pode remover
-v
e ver onde está a sobreposição:auf
Aparentemente, a palavra está nos dois idiomas ... bem, pelo menos está no meuwords
arquivo, portanto, pode ser um pouco de tentativa e erro para refinar a lista de palavras, conforme necessário.NOTA: Eu sabia que era a palavra
auf
porque agrep
coloria de vermelho, que não aparece na saída acima devido à natureza limitada do SE 8-).fonte
grep -wf ...
faz. Com um melhor suprimento de palavras, essa abordagem seria a mais direta. A outra solução (de Stephane) depende da estruturação dos dados e não os analisa de maneira contextual, a abordagem de msw parece ter melhores pernas para mim.Parece um
.srt
arquivo. Se for, e se o número de linhas em inglês por legenda for sempre o mesmo que o número de linhas em alemão, você poderá usar:Onde
old.srt
enew.srt
seus arquivos de entrada e saída escolhidos.fonte