Eu tenho um arquivo com este conteúdo:
# new file
text in file 1
# new file
text in file 2
# new file
text in file 3
O padrão aqui é # new file
.
Em vez de salvar cada arquivo em xx00, xx01 e xx02, salvei em arquivos específicos: another file
, file new
, last one
.
Os 3 arquivos existem no diretório atual, então quero fornecê-los como array e substituí-los:
csplit -z infile '/# new file/' "${array[*]}"
A matriz pode ser fornecida diretamente
array=('another file' 'file new' 'last one')
echo ${array[*]}
another file file new last one
Ou liste o diretório atual
array=($(find . -type f))
echo ${array[*]}
./another file ./file new ./last one
Uma modificação deste script poderia ser a solução:
awk -v file="1" -v occur="2" '
{
print > (file".txt")
}
/^\$\$\$\$$/{
count++
if(count%occur==0){
if(file){
close(file".txt")
++file
}
}
}
' Input_file
Eu ainda consideraria usar
csplit
, mas depois renomearia os arquivos gerados.Uso
Isso funciona mesmo com espaços e caracteres não ASCII, tanto dentro do arquivo de texto quanto nos nomes dos arquivos, sem usar arquivos temporários:
infile
:O comando awk deve ser fornecido com os nomes dos arquivos como argumentos individuais, usando aspas simples para não expandir o shell (aspas duplas), neste
split.sh
script:O console fica assim:
Se os argumentos forem passados como saída de outro comando (os arquivos devem existir anteriormente no sistema de arquivos):
divide os argumentos pelo espaço:
Para resolver isso, passe os argumentos como um array para o awk, separados por uma nova linha e não por um espaço, com este
split.sh
script:Agora o resultado é:
O número de arquivos nos quais gravar deve ser pelo menos igual às divisões que serão realizadas. Se for mais, o resto será ignorado.