bash 反转字符串中的字符顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11461625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
reverse the order of characters in a string
提问by MadHatter
In string "12345", out string "54321". Preferably without third party tools and regex.
输入字符串“12345”,输出字符串“54321”。最好没有第三方工具和正则表达式。
采纳答案by MadHatter
Simple:
简单的:
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"
Output:
输出:
$ bash rev
var: 12345, rev: 54321
回答by MadHatter
I know you said "without third-party tools", but sometimes a tool is just too obviously the right one, plus it's installed on most linux systems by default:
我知道你说“没有第三方工具”,但有时一个工具显然是正确的,而且它默认安装在大多数 linux 系统上:
[madhatta@risby tmp]$ echo 12345|rev
54321
回答by Lri
rev | tail -r
(BSD) or rev | tac
(GNU) also reverse lines:
rev | tail -r
(BSD) 或rev | tac
(GNU) 也反转行:
$ rev <<< $'12\n34' | tail -r
43
21
$ rev <<< $'12\n34' | gtac
43
21
If LC_CTYPE is C, rev reverses the bytes of multibyte characters:
如果 LC_CTYPE 是 C,rev 反转多字节字符的字节:
$ LC_CTYPE=C rev <<< あの
??め?
$ export LC_ALL=C; LC_ALL=en_US.UTF-8 rev <<< あの
のあ
回答by Nick
Presume that a variable 'var' has the value '123'
假设变量“var”的值为“123”
var="123"
Reverse the string and store in a new variable 'rav':
反转字符串并存储在新变量 'rav' 中:
rav=$(echo $var | rev)
You'll see the 'rav' has the value of '321' using echo.
使用 echo,您将看到 'rav' 的值为 '321'。
echo $rav
回答by Nick
A bash solution improving over @osdyng answer (my edit was not accepted):
改进了@osdyng 答案的 bash 解决方案(我的编辑未被接受):
var="12345" rev=""
for(( i=0 ; i<${#var} ; i++ )); do rev="${var:i:1}$rev"; done
echo "var: $var, rev: $rev"
Or an even simpler (bash) loop:
或者更简单的(bash)循环:
var= len="${#var}" i=0 rev=""
while (( i<len )); do rev="${var:i++:1}$rev"; done
echo "var: $var, rev: $rev"
A POSIX solution:
POSIX 解决方案:
var="12345" rev="" i=1
while [ "$i" -le "${#var}" ]
do rev="$(echo "$var" | awk -v i="$i" '{print(substr(a=12345
len=${#a}
for ((i=1;i<len;i++)); do a=$a${a: -i*2:1}; done; a=${a:len-1}
echo $a
,i,1))}')$rev"
: $(( i+=1 ))
done
echo "var: $var, rev: $rev"
Note: This works on multi byte strings. Cut solutions will work only in ASCII (1 byte) strings.
注意:这适用于多字节字符串。Cut 解决方案仅适用于 ASCII(1 字节)字符串。
回答by Paused until further notice.
This reverses the string "in place":
这将反转字符串“就地”:
for ((i=0;i<len;i++)); do a=${a:i*2:1}$a; done; a=${a:0:len}
or the third line could be:
或者第三行可能是:
for ((i=1;i<len;i++)); do a=${a:0:len-i-1}${a: -i:i+1}${a:len-i-1:1}; done
or
或者
awk -F '' '{ for(i=NF; i; i--) printf("%c", $i); print "" }'
回答by Michael Back
For those without rev(recommended), there is the following simple awksolution that splits fields on the null string (every character is a separate field) and prints in reverse:
对于那些没有rev(推荐)的人,有以下简单的awk解决方案,可以拆分空字符串上的字段(每个字符都是一个单独的字段)并反向打印:
echo "var: $var, rev: $rev"
The above awkcode is POSIX compliant. As a compliant awkimplementation is guaranteed to be on every POSIX compliant OS, the solution should thus not be thought of as "3rd-party." This code will likely be more concise and understandable than a pure POSIX sh(or bash) solution.
上面的awk代码符合 POSIX 标准。由于在每个符合 POSIX 的操作系统上都保证了兼容的awk实现,因此不应将该解决方案视为“第 3 方”。与纯 POSIX sh(或bash)解决方案相比,此代码可能更简洁易懂。
(; I do not know if you consider the null string to -F a regex... ;)
(; 我不知道你是否认为 -F 是一个正则表达式的空字符串......;)
回答by Isaac
If var=12345
:
如果var=12345
:
bashfor((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
shc=$var; while [ "$c" ]; do rev=$rev${c#"${c%?}"}; c=${c%?}; done
嘘c=$var; while [ "$c" ]; do rev=$rev${c#"${c%?}"}; c=${c%?}; done
$ rev
var: 12345, rev: 54321
Run it:
运行:
echo '!!!esreveR si sihT' | grep -o . | tac | tr -d '\n' ; echo
echo '!!!esreveR si sihT' | fold -w 1 | tac | tr -d '\n' ; echo
回答by David Heffernan
Some simple methods of reversing a string
反转字符串的一些简单方法
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
Convert to hex values then reverse
转换为十六进制值然后反转
$ echo 123456 | sed $'s/./&\\n/g' | sed -ne $'x;H;${x;s/\n//g;p;}'
654321
回答by ghoti
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.
似乎没有人发布过sed
解决方案,所以这里有一个适用于非 GNU sed的解决方案(所以我不会认为它是“第 3 方”)。它确实使用 regex 捕获单个字符.
,但这是唯一的正则表达式。
In two stages:
分两个阶段:
##代码##This uses bash format substitution to include newlines in the scripts (since the question is tagged bash). 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.
这使用 bash 格式替换在脚本中包含换行符(因为问题被标记为bash)。它的工作原理是首先将输入字符串每个字符分成一行,然后将每个字符插入到保持缓冲区的开头。
x
swaps the hold space and the pattern space, andH
H appends the (current) pattern space to the hold space.
x
交换保持空间和模式空间,和H
H 将(当前)模式空间附加到保持空间。
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.
这应该适用于任何单个字符串,但它会将多行输入连接成单个输出字符串。