Respostas relacionadas, mas sem respostas satisfatórias: Como posso dividir um arquivo de texto grande em pedaços de 500 palavras ou mais?
Estou tentando pegar um arquivo de texto ( http://mattmahoney.net/dc/text8.zip ) com> 10 ^ 7 palavras, tudo em uma linha, e dividi-lo em linhas com N palavras cada. Minha abordagem atual funciona, mas é bastante lenta e feia (usando o shell script):
i=0
for word in $(sed -e 's/\s\+/\n/g' input.txt)
do
echo -n "${word} " > output.txt
let "i=i+1"
if [ "$i" -eq "1000" ]
then
echo > output.txt
let "i=0"
fi
done
Alguma dica de como posso tornar isso mais rápido ou mais compacto?
text-processing
sed
awk
split
Cory Schillaci
fonte
fonte
Respostas:
Supondo que sua definição de palavra seja uma sequência de caracteres não em branco separados por espaços em branco, aqui está uma
awk
solução para seu arquivo de linha únicafonte
Use
xargs
(17 segundos):Ele usa a
-n
bandeira daxargs
qual define o número máximo de argumentos. Apenas mude1000
para500
ou o limite que desejar.Eu criei um arquivo de teste com 10 ^ 7 palavras:
Aqui estão as estatísticas de tempo:
fonte
xargs
's comportamento de extracção Citaçãon
mais lento será, só para você saber. Com-n10
I cancelada após cerca de 8 minutos de espera ...Perl parece surpreendentemente bom nisso:
Crie um arquivo com 10.000.000 de palavras separadas por espaço
Agora, perl para adicionar uma nova linha após cada 1.000 palavras
Cronometragem
verificar resultados
A solução awk aceita levou pouco mais de 5 segundos no meu arquivo de entrada.
fonte
Não é realmente adequado quando
N
um número grande de palavras é um número grande, mas se for um número pequeno (e, idealmente, não há espaços iniciais / finais no seu arquivo de uma linha), isso deve ser bastante rápido (por exemplo, 5 palavras por linha):fonte
paste
string rapidamente. Por exemplo:tr -s '[[:blank:]]' '\n' < text8 | paste -d' ' $(perl -le 'print "- " x 1000')
set
etc ... e mesmo assim, há um número máximo sytem específico de argumentos (eu não estou familiarizado com todos os sabores depaste
mas Eu acho que com algumas implementações existem limites quanto ao não de args arquivos / de entrada e / ou comprimento da linha de saída ...).O mesmo comando sed pode ser simplificado especificando quantos padrões de espaço de palavras você deseja corresponder. Eu não tinha nenhum arquivo grande de cadeia de caracteres para testá-lo, mas sem os loops no script original, ele deve ser executado o mais rápido que o processador puder transmitir os dados. Benefício adicional: funcionará igualmente bem em arquivos de várias linhas.
fonte
O venerável
fmt(1)
comando, embora não esteja operando estritamente em "um determinado número de palavras", pode rapidamente quebrar linhas longas para uma determinada largura de objetivo (ou máxima):Ou com perl moderno, para um número específico de palavras, digamos, 10, e assumindo um único espaço como o limite da palavra:
fonte
O
pr
comando coreutils é outro candidato: a única dobra parece ser que é necessário forçar a largura da página a ser grande o suficiente para acomodar a largura da saída.Usando um arquivo criado usando o gerador de 10.000.000 de palavras de @ Glenn_Jackman,
onde as contagens são confirmadas da seguinte forma
[A solução perl de Glenn ainda é um pouco mais rápida, ~ 1,8s nesta máquina].
fonte
em Go eu tentaria assim
fonte