обратный порядок символов в строке
в строке "12345", из строки"54321". Желательно без сторонних инструментов и регулярных выражений.
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 байт).
Это, конечно, можно сократить, но это должно быть просто понять: финал
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 регулярным выражением... ;)
некоторые простые методы реверсирования строки
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