обратный порядок символов в строке


в строке "12345", из строки"54321". Желательно без сторонних инструментов и регулярных выражений.

11 54

11 ответов:

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

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

просто:

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

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 <<< あの
のあ

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

var="123"

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

rav=$(echo $var | rev)

вы увидите, что ' rav 'имеет значение' 321 ' с помощью echo.

echo $rav

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

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

решение 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=   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(,i,1))}')$rev"
       : $(( i+=1 ))
done

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

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

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

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

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

в два этапа:

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

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

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

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

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

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

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

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

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

если 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

некоторые простые методы реверсирования строки

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