
Quiero encontrar todas las secuencias que están en orden alfabético en un archivo de texto, sin ordenarlas.
Ejemplo: suponiendo que el archivo de texto se vea así:
aedftg
wqof
abcdef
oufn
pqrs
aabcd
la salida debe ser
abcdef
pqrs
además sin repetir caracteres como aabcd
.
Respuesta1
Una opción, codificada para inglés:
grep -ix 'a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*' input
Crédito aNinjaOsoMonopor plasmar la idea que estaba germinando en mi cabeza; Modifiqué la expresión regular para permitir caracteres repetidos ( aabcc
).
Otra opción:
Usar sort
para verificar el orden de clasificación específico de la configuración regional es una mejor manera de hacerlo, de modo que no tenga que codificar el alfabeto. Comomikejonesey lo hizo, esto significa que tienes que dividir los caracteres de la línea en líneas separadas. Hice esto con un script de shell (usando un shell moderno que admite la expansión de subcadenas) para evitar la llamada a sed, y que también usa sort
la opción -c para indicar si la entrada ya está ordenada o no:
while IFS= read -r line
do
for((i=0; i < ${#line}; i++))
do
printf '%s\n' "${line:i:1}"
done | sort -c 2>/dev/null && printf '%s\n' "$line"
done
Si sort
encuentra una discrepancia, la envía a stderr, pero solo nos importa el código de retorno, por lo que descarto stderr.
Una demostración con una entrada que no está en inglés (los $
caracteres son los mensajes del shell):
$ cat input
αβγα
αβγ
$ ./sorted2 < input
αβγ
$
Respuesta2
Solo para completar, una awk
solución basada en , donde se intercambia la relación habitual de patrón y datos:
awk 'BEGIN{ref="abcdefghijklmnopqrstuvwxyz"} ref ~ $0' file.txt
Esto interpretará las líneas del archivo como expresiones regulares con las que se compara la cadena de "referencia" de caracteres ordenados desde a
hasta . z
Sólo si hay una coincidencia (lo que significa que la cadena en la línea es una subcadena dea ... z
), se imprimirá la línea.
Respuesta3
perl -MPOSIX -Mopen=locale -lne '
print unless m{(.)(.)(?(?{strcoll($1, $2) < 0})(*FAIL))}' < file
Imprimiría las líneas defile
excepto aquellas que contengan un carácter que no intercale después del anterior en la configuración regional del usuario.
Respuesta4
cat homework.txt | while read aline; do
stringORIG=$(echo -n "$aline" | sed 's/\(.\)/\1\n/g')
stringABC=$(echo -n "$aline" | sed 's/\(.\)/\1\n/g' | sort)
if [ "$stringORIG" == "$stringABC" ]; then
echo "$aline"
fi
done
.
abcdef
pqrs
ps... si no desea utilizar el comando sort, puede convertir cada carácter a int y tener una declaración if para verificar que el último carácter sea menor que el siguiente...