Probar si la serie entera está aumentando estrictamente


1

Me gustaría probar si una lista de valores enteros (por ejemplo, almacenados en un archivo, uno por línea) está aumentando estrictamente, utilizando un script bash.

¿Hay alguna manera simple / concisa de lograr eso?

Respuestas:


6

Compruebe si el contenido del archivo permanece igual después de ordenar numéricamente y filtrar líneas duplicadas:

cmp file <(sort -n file | uniq)

Al menos GNU sortpuede hacer esta verificación directamente:

sort -c -u -n file

(La documentación POSIX tambiénsort menciona esto, por lo que debería ser compatible en todas partes).


Pero eso no funcionará para un aumento estricto , ¿verdad?
sdabet

@fiddler si omite la parte "filtrar líneas duplicadas" obtendrá su solución para una secuencia estrictamente creciente
roaima

La sortsolución parece perfecta.
sdabet

Tenga en cuenta que la ordenación GNU (a diferencia de la ordenación Solaris, por ejemplo) parece leer la entrada completamente antes de informar el trastorno, incluso si el trastorno está en la segunda línea.
Stéphane Chazelas

1
Sí, incluso cuando se verifica , comienza llenando un búfer .
Stephen Kitt

2

Si quiere decir, compruebe que cada línea es un entero decimal que es uno más el entero decimal en la línea anterior, luego:

awk 'NR == 1 {n = $0; next}
     $0 != n+1 {status = 1; exit}
     {n = $0}
     END {exit status}'

Reemplace $0 != n+1con $0 <= npara verificar el aumento estricto por cualquier valor, no solo uno. Sin embargo, en ese caso, probablemente prefiera el sort -cenfoque a menos que desee que deje de leer en el primer trastorno o desee admitir formatos de número (hexadecimal, notación de coma flotante ...) no admitidos sort(como cuando su ordenación no no apoyo -g)


estrictamente creciente simplemente significa que para una secuencia entera, el valor actual es mayor que el anterior. No supone que esté aumentando en uno, o incluso en cualquier cantidad regular. Solo que cada número es la secuencia es más grande que la anterior.
roaima

1

Con awk:

awk 'length(p)&&++p!=$0{print "Not OK";exit};{p=$0}' file

para aumentar uno por línea. Para verificar la corriente es más grande que la anterior:

awk 'length(p)&&++p<=$0{print "Not OK";exit};{p=$0}' file

0

La versión extremadamente concisa sería algo como esto

#!/bin/bash
awk 'NR > 1 && $1 < prev { printf( "error at line %d\n", NR); exit; } { prev = $1 } '  $1

Este código no conciso sería

#!/bin/bash
l=1     #line number count
p=0     #previous line value
for f in `cat $1`
do
    if [ \( "$f" -lt "$p" \) -a \( "$l" -ne "1" \) ]   #chk for all lines, except first
        then    echo "$f is less than $p on Line $l"
        break
    else
        p=$f  #set previous
    fi
    l=$(expr $l + 1)   #increment line number
done
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.