vuelta una programacion para palabra invertir inversa funcion darle dar como caracteres cadenas cadena ats algoritmo bash

bash - programacion - invertir el orden de los caracteres en una cadena



invertir una cadena en c (11)

Algunos métodos simples de revertir una cadena

echo ''!!!esreveR si sihT'' | grep -o . | tac | tr -d ''/n'' ; echo echo ''!!!esreveR si sihT'' | fold -w 1 | tac | tr -d ''/n'' ; echo

Convertir a valores hexadecimales y luego invertir

echo ''!!!esreveR si sihT'' | xxd -p | grep -o .. | tac | xxd -r -p ; echo echo ''!!!esreveR si sihT'' | xxd -p | fold -w 2 | tac | xxd -r -p ; echo

En la cadena "12345", fuera de la cadena "54321". Preferiblemente sin herramientas de terceros y regex.


Esto invierte la cadena "en su lugar":

a=12345 len=${#a} for ((i=1;i<len;i++)); do a=$a${a: -i*2:1}; done; a=${a:len-1} echo $a

o la tercera línea podría ser:

for ((i=0;i<len;i++)); do a=${a:i*2:1}$a; done; a=${a:0:len}

o

for ((i=1;i<len;i++)); do a=${a:0:len-i-1}${a: -i:i+1}${a:len-i-1:1}; done


Nadie parece haber publicado una solución sed , así que aquí hay una que funciona en sed no GNU (por lo que no la consideraría "tercero"). Captura solo caracteres utilizando la expresión regular . , pero esa es la única expresión regular.

En dos etapas:

$ echo 123456 | sed $''s/./&///n/g'' | sed -ne $''x;H;${x;s///n//g;p;}'' 654321

Esto utiliza la sustitución del formato bash para incluir nuevas líneas en los scripts (ya que la pregunta está etiquetada como bash ). Funciona separando primero la cadena de entrada en una línea por carácter, y luego insertando cada carácter en el comienzo del búfer de retención.

  • x intercambia el espacio de retención y el espacio de patrón, y
  • H H agrega el espacio del patrón (actual) al espacio de retención.

Por lo tanto, para cada personaje, colocamos ese carácter en el espacio de retención, luego le agregamos el espacio de retención anterior, invirtiendo así la entrada. El comando final elimina las nuevas líneas para reconstruir la cadena original.

Esto debería funcionar para cualquier cadena única, pero concatenará la entrada de varias líneas en una sola cadena de salida.


Para aquellos sin rev (recomendado), existe la siguiente solución awk simple que divide los campos en la cadena nula (cada carácter es un campo separado) y se imprime al revés:

awk -F '''' ''{ for(i=NF; i>0; i--) printf("%s", $i); print "" }''

El código awk anterior es compatible con POSIX. Como se garantiza que una implementación awk compatible se encuentra en todos los sistemas operativos compatibles con POSIX, la solución no debe considerarse como "de terceros". Este código probablemente sea más conciso y comprensible que una solución pura POSIX sh (o bash ).

(; No sé si considera que la cadena nula es -F una expresión regular ...;)


Por supuesto, esto puede acortarse, pero debería ser fácil de entender: la print final agrega la nueva línea.

echo 12345 | awk ''{for (i = length($0); i > 0; i--) {printf("%s", substr($0, i, 1));} print "";}''


Sé que usted dijo "sin herramientas de terceros", pero a veces una herramienta es obviamente la correcta, además de que está instalada en la mayoría de los sistemas Linux por defecto:

[madhatta@risby tmp]$ echo 12345|rev 54321


Sencillo:

var="12345" copy=${var} len=${#copy} for((i=$len-1;i>=0;i--)); do rev="$rev${copy:$i:1}"; done echo "var: $var, rev: $rev"

Salida:

$ bash rev var: 12345, rev: 54321


Si var=12345 :

bash for((i=0;i<${#var};i++)); do rev="$rev${var:~i:1}"; done for((i=0;i<${#var};i++)); do rev="$rev${var:~i:1}"; done

sh c=$var; while [ "$c" ]; do rev=$rev${c#"${c%?}"}; c=${c%?}; done c=$var; while [ "$c" ]; do rev=$rev${c#"${c%?}"}; c=${c%?}; done

echo "var: $var, rev: $rev"

Ejecutarlo:

$ rev var: 12345, rev: 54321


Supongamos que una variable ''var'' tiene el valor ''123''

var="123"

Invierta la cadena y almacene en una nueva variable ''rav'':

rav=$(echo $var | rev)

Verás que ''rav'' tiene el valor de ''321'' usando eco.

echo $rav


Una solución de bash que mejora sobre la respuesta de @osdyng (mi edición no fue aceptada):

var="12345" rev="" for(( i=0 ; i<${#var} ; i++ )); do rev="${var:i:1}$rev"; done echo "var: $var, rev: $rev"

O un bucle aún más simple (bash):

var=$1 len="${#var}" i=0 rev="" while (( i<len )); do rev="${var:i++:1}$rev"; done echo "var: $var, rev: $rev"

Una solución POSIX:

var="12345" rev="" i=1 while [ "$i" -le "${#var}" ] do rev="$(echo "$var" | awk -v i="$i" ''{print(substr($0,i,1))}'')$rev" : $(( i+=1 )) done echo "var: $var, rev: $rev"

Nota: Esto funciona en cadenas de múltiples bytes. Las soluciones de corte solo funcionarán en cadenas ASCII (1 byte).


rev | tail -r rev | tail -r (BSD) o rev | tac rev | tac (GNU) también líneas inversas:

$ rev <<< $''12/n34'' | tail -r 43 21 $ rev <<< $''12/n34'' | gtac 43 21

Si LC_CTYPE es C, rev revierte los bytes de los caracteres multibyte:

$ LC_CTYPE=C rev <<< あの ��め� $ export LC_ALL=C; LC_ALL=en_US.UTF-8 rev <<< あの のあ