Отменить порядок символов в строке

В строке "12345" вывести строку "54321". Предпочтительно без сторонних инструментов и регулярных выражений.

Ответ 1

Простой:

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"

Вывод:

$ bash rev
var: 12345, rev: 54321

Ответ 2

Я знаю, что вы сказали "без сторонних инструментов", но иногда инструмент слишком явно прав, плюс он установлен по умолчанию для большинства Linux-систем:

[[email protected] tmp]$ echo 12345|rev
54321

Ответ 3

rev | tail -r (BSD) или rev | tac (GNU) также обратные линии:

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

Если LC_CTYPE - C, rev меняет байты многобайтовых символов:

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

Ответ 4

Предположим, что переменная 'var' имеет значение '123'

var="123"

Отмените строку и сохраните в новой переменной "rav":

rav=$(echo $var | rev)

Вы увидите, что "rav" имеет значение "321", используя эхо.

echo $rav

Ответ 5

A bash решение, улучшающееся по сравнению с ответом @osdyng (мое редактирование не было принято):

var="12345"     rev=""

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

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

Или еще более простой (bash) цикл:

var=$1   len="${#var}"   i=0   rev=""

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

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

Решение 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"

Примечание. Это работает с несколькими байтовыми строками. Решения для разреза будут работать только в строках ASCII (1 байт).

Ответ 6

Это отменяет строку "на месте":

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

или третья строка может быть:

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

или

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

Ответ 7

Для тех, у кого нет rev (рекомендуется), существует следующее простое решение awk, которое разбивает поля на пустой строке (каждый символ является отдельным полем) и печатает в обратном порядке:

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

Приведенный выше код awk соответствует POSIX. Поскольку совместимая реализация awk гарантированно присутствует на каждой POSIX-совместимой ОС, решение, таким образом, не должно рассматриваться как "стороннее". Этот код, вероятно, будет более кратким и понятным, чем чисто POSIX sh (или bash) решение.

(; Я не знаю, считаете ли вы пустую строку для -F регулярным выражением...;)

Ответ 8

Если var=12345:

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

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

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

Запустите его:

$ rev
var: 12345, rev: 54321

Ответ 9

Это, конечно, может быть сокращено, но это должно быть понятным: окончательный print добавляет новую строку.

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

Ответ 10

Некоторые простые методы для изменения строки

echo '!!!esreveR si sihT' | grep -o . | tac | tr -d '\n' ; echo

echo '!!!esreveR si sihT' | fold -w 1 | tac | tr -d '\n' ; echo

Преобразовать в шестнадцатеричные значения, а затем отменить

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

Ответ 11

Похоже, никто не опубликовал решение sed, поэтому здесь оно работает в non-GNU sed (поэтому я бы не стал считать его "сторонним разработчиком"). Он захватывает отдельные символы с помощью регулярных выражений . , но это единственное регулярное выражение.

В два этапа:

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

При этом используется замена формата bash для включения новых строк в сценарии (поскольку вопрос помечен ). Он работает, сначала разделяя входную строку на одну строку на символ, а затем вставляя каждый символ в начало буфера хранения.

  • x меняет пространство удержания и пространство шаблона, и
  • H H добавляет (текущее) пространство образца к пространству удержания.

Таким образом, для каждого символа мы помещаем этот символ в пространство удержания, затем добавляем к нему старое пространство удержания, таким образом, изменяя ввод. Последняя команда удаляет символы новой строки, чтобы восстановить исходную строку.

Это должно работать для любой отдельной строки, но объединит многострочный ввод в одну выходную строку.

Ответ 12

читать слово

reve='echo "$word" | awk '{for(i=length($0); i>0;i--) printf (substr($0,i,1));}''
echo  "$reve"