Program Tip

문자열의 문자 순서를 반대로

programtip 2020. 11. 9. 20:31
반응형

문자열의 문자 순서를 반대로


문자열 "12345"에서 문자열 "54321"을 출력합니다. 타사 도구 및 정규식이없는 것이 바람직합니다.


나는 당신이 "타사 도구없이"라고 말한 것을 알고 있지만, 때로는 도구가 너무 명백하게 옳은 것이고, 기본적으로 대부분의 리눅스 시스템에 설치되어 있습니다.

[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 $rav

@osdyng 답변보다 개선되는 bash 솔루션 (내 편집이 허용되지 않음) :

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 바이트) 문자열에서만 작동합니다.


이렇게하면 "제자리에"문자열이 반전됩니다.

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

만약 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

rev가 없는 경우 (권장), 널 문자열 (모든 문자는 별도의 필드)에서 필드를 분할하고 반대로 인쇄 하는 다음과 같은 간단한 awk 솔루션이 있습니다.

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

위의 awk 코드는 POSIX를 준수합니다. 호환되는 awk 구현은 모든 POSIX 호환 OS에서 보장되므로 솔루션을 "타사"로 간주해서는 안됩니다. 이 코드는 순수한 POSIX sh (또는 bash ) 솔루션 보다 더 간결하고 이해하기 쉽습니다 .

(; I do not know if you consider the null string to -F a regex... ;)


This can of course be shortened, but it should be simple to understand: the final print adds the newline.

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

Some simple methods of reversing a string

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

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

Convert to hex values then reverse

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

Nobody appears to have posted a sed solution, so here's one that works in non-GNU sed (so I wouldn't consider it "3rd party"). It does capture single characters using the regex ., but that's the only regex.

In two stages:

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

This uses bash format substitution to include newlines in the scripts (since the question is tagged ). It works by first separating the input string into one line per character, and then by inserting each character into the beginning of the hold buffer.

  • x swaps the hold space and the pattern space, and
  • H H appends the (current) pattern space to the hold space.

So for every character, we place that character into the hold space, then append the old hold space to it, thus reversing the input. The final command removes the newlines in order to reconstruct the original string.

This should work for any single string, but it will concatenate multi-line input into a single output string.

참고URL : https://stackoverflow.com/questions/11461625/reverse-the-order-of-characters-in-a-string

반응형