Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
127 lines (114 sloc) 3.67 KB
# ----------------------------------------------------------------------------
# Mistura linha a linha 2 ou mais arquivos, mantendo a sequência.
# Opções:
# -o <arquivo> - Define o arquivo de saída.
# -m - Toma como base o arquivo com menos linhas.
# -M - Toma como base o arquivo com mais linhas.
# -<numero> - Toma como base o arquivo na posição especificada.
# -p <relação de linhas> - numero de linhas de cada arquivo de origem.
# Obs1.: A relação são números de linhas de cada arquivo correspondente na
# sequência, justapostos separados por vírgula (,).
# Obs2.: Se a quantidade de linhas na relação for menor que a quantidade de
# arquivos, os arquivos excedentes adotam a último valor na relação.
#
# Sem opção, toma como base o primeiro arquivo declarado.
#
# Uso: zzmix [-m | -M | -<num>] [-o <arq>] [-p <relação>] arq1 arq2 [arqN] ...
# Ex.: zzmix -m arquivo1 arquivo2 arquivo3 # Base no arquivo com menos linhas
# zzmix -2 arquivo1 arquivo2 arquivo3 # Base no segundo arquivo
# zzmix -o out.txt arquivo1 arquivo2 # Mixando para o arquivo out.txt
# zzmix -p 2,5,6 arq1 arq2 arq3
# # 2 linhas do arq1, 5 linhas do arq2 e 6 linhas do arq3,
# # e repete a sequência até o final.
#
# Autor: Itamar <itamarnet (a) yahoo com br>
# Desde: 2013-11-01
# Versão: 3
# Licença: GPL
# Tags: arquivo, manipulação
# ----------------------------------------------------------------------------
zzmix ()
{
zzzz -h mix "$1" && return
local lin_arq arquivo arq_saida arq_ref
local passos=1
local linhas=0
local tipo=1
# Opção -m ou -M, -numero ou -o
while test "${1#-}" != "$1"
do
if test '-o' = "$1"
then
arq_saida="$2"
shift
elif test '-p' = "$1"
then
passos="$2"
shift
else
tipo="${1#-}"
fi
shift
done
test -n "$2" || { zztool -e uso mix; return 1; }
for arquivo
do
# Especificar se vai se orientar pelo arquivo com mais ou menos linhas
if test 'm' = "$tipo" || test 'M' = "$tipo"
then
lin_arq=$(zztool num_linhas "$arquivo")
if test 'M' = "$tipo" && test $lin_arq -gt $linhas
then
linhas=$lin_arq
arq_ref=$arquivo
fi
if test 'm' = "$tipo" && (test $lin_arq -lt $linhas || test $linhas -eq 0)
then
linhas=$lin_arq
arq_ref=$arquivo
fi
fi
# Verifica se arquivos são legíveis
zztool arquivo_legivel "$arquivo" || { zztool erro "Um ou mais arquivos inexistentes ou ilegíveis."; return 1; }
done
# Se opção é um numero, o arquivo base para as linhas é o mesmo da posição equivalente
if zztool testa_numero $tipo && test $tipo -le $#
then
arq_ref=$(awk -v arg=$tipo 'BEGIN { print ARGV[arg] }' $* 2>/dev/null)
linhas=$(zztool num_linhas "$arq_ref")
fi
# Sem quantidade de linhas mínima não há mistura.
test "$linhas" -eq 0 && { zztool erro "Não há linhas para serem \"mixadas\"."; return 1; }
# Onde a "mixagem" ocorre efetivamente.
awk -v linhas_awk=$linhas -v passos_awk="$passos" -v arq_ref_awk="$arq_ref" -v saida_awk="$arq_saida" '
BEGIN {
qtde_passos = split(passos_awk, passo, ",")
if (qtde_passos < ARGC)
{
ultimo_valor = passo[qtde_passos]
for (i = qtde_passos+1; i <= ARGC; i++) {
passo[i] = ultimo_valor
}
}
div_linhas = 1
for (i = 1; i <= ARGC-1; i++) {
if (arq_ref_awk == ARGV[i]) {
div_linhas = passo[i]
}
}
bloco_linhas=int(linhas_awk/div_linhas) + (linhas_awk/div_linhas==int(linhas_awk/div_linhas)?0:1)
for (i = 1; i <= bloco_linhas; i++) {
for(j = 1; j < ARGC; j++) {
for (k = 1; k <= passo[j]; k++)
{
if ((getline linha < ARGV[j]) > 0) {
if (length(saida_awk)>0)
print linha >> saida_awk
else
print linha
}
}
}
}
}' $* 2>/dev/null
}