quiero dividir mi$archivoque contieneXlíneas por la mitad y verifique cuántas líneas contienen "muerto" en un registro. Comencé con lo siguiente:
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
La salida del primer sed
comando está bien, pero cuando se sustituye egrep
en el rango sed
sale mal:
DeadOrAlive 5 2
-bash: ${half},${egrep -c . $file}p: bad substitution
¿Existe una forma más eficiente de dividir el archivo bash
?
Respuesta1
Usando
wc
,head
ytail
: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]
Respuesta2
Aquí hay una solución 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
Recopilamos en la matriz a
los números de línea de las coincidencias. Luego calculamos cuántos números de línea en la matriz son más pequeños que la línea del medio; su recuento se asigna a la primera partición. (Tenemos que usarlo i-1
porque ya hemos pasado el punto de partición cuando salimos break
del bucle).
En general, conviene evitar releer el mismo archivo muchas veces, especialmente si puede ser grande; y en segundo lugar, intentar minimizar el número de procesos.
No está claro qué espera que contenga el campo de salida del medio. Si el archivo contiene un número impar de líneas, la primera "mitad" contendrá una línea menos que la segunda partición. (Esto no es difícil de cambiar, pero hay que decidir de una forma u otra).