quero dividir meu$arquivocontendoxlinhas pela metade e verifique quantas linhas contêm "morto"em um log. Comecei com o seguinte:
half=`expr $(egrep -c . $file) / 2`
sed -n 1,${half}p $file |
xargs echo $file $half $(egrep -c dead $I) > log_1
sed -n ${half},${egrep -c . $file}p |
xargs echo $file $half $(egrep -c dead $I) > log_2
a saída do primeiro sed
comando está ok, mas ao substituir egrep
no intervalo sed
dá errado:
DeadOrAlive 5 2
-bash: ${half},${egrep -c . $file}p: bad substitution
Existe uma maneira mais eficiente de dividir o arquivo bash
?
Responder1
Usando
wc
,head
etail
:half=$(( $(wc -l "$file")/2 )) head -$half | egrep -c dead | xargs echo "$file" $half > log_1 tail -$half | egrep -c dead | xargs echo "$file" $half > log_2
Usando
split
:split -a1 --numeric-suffixes=1 -n 'l/2' "$file" "$file"_ echo "$file" "$file"_1 $(egrep -c dead "$file_1") > log_1 echo "$file" "$file"_2 $(egrep -c dead "$file"_2) > log_2 rm "$file"_[12]
Responder2
Aqui está uma solução Awk.
awk '/dead/ { a[++n] = NR }
END { for (i=1; i<=n; i++) if (a[i] > NR/2) break
print ARGV, int(NR/2), i-1 >"log_1";
print ARGV, int(NR/2)+(int(NR/2)!=NR/2), n-i+1 >"log_2" }' file
Coletamos no array a
os números das linhas das correspondências. Em seguida, descobrimos quantos números de linha na matriz são menores que a linha do meio; sua contagem é atribuída à primeira partição. (Temos que usar i-1
porque já passamos do ponto de particionamento quando saímos break
do loop.)
Em geral, você deseja evitar reler o mesmo arquivo muitas vezes, especialmente se ele for grande; e em segundo lugar, tente minimizar o número de processos.
Não está claro o que você espera que o campo de saída intermediário contenha. Se o arquivo contiver um número ímpar de linhas, a primeira “metade” conterá uma linha a menos que a segunda partição. (Isso não é difícil de mudar, mas você tem que decidir de uma forma ou de outra.)