在字符串“ 12345”中,在字符串“ 54321”中。最好没有第三方工具和正则表达式。
Answers:
我知道您说过“没有第三方工具”,但是有时候工具显然是正确的工具,而且默认情况下它已安装在大多数linux系统上:
[madhatta@risby tmp]$ echo 12345|rev
54321
rev <<< 12345
使用bash,zsh和ksh。(不是破折号或csh。)
echo '\xff' |rev
。我从来没有说过这样做echo -e
会行得通,所以在不行的时候让我over之以鼻似乎有点苛刻。
rev
在每行上独立起作用,并且似乎没有任何命令行选项可以对此进行修改。此外,如@Equidamoid的示例所示(顺便说一下,这与无关echo -e
),它假定字符串是正确编码的字符序列。如果您需要按字节反转某些内容(例如,如果您不处理二进制数据而不是实际文本),则此解决方案无效。[注意:为解决格式问题,我删除了此评论并重新发布。抱歉,可能会产生幻影通知。]
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 <<< あの
のあ
tac
。请注意,tac
与\n
使用该-s
选项相比,它支持传递不同的定界符。
一个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字节)字符串。
awk '{for(i=length($0);i;i--)printf "%s",substr($0,i,1); print ""}'
甚至awk '{for(i=length($0);i;i--)x=x substr($0,i,1); print x}'
反转字符串的一些简单方法
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
似乎没有人发布过sed
解决方案,所以这里有一个可以在非GNU sed中使用的解决方案(因此,我不认为它是“第三方”)。它确实使用正则表达式捕获单个字符.
,但这是唯一的regex。
分两个阶段:
$ echo 123456 | sed $'s/./&\\\n/g' | sed -ne $'x;H;${x;s/\\n//g;p;}'
654321
这使用bash格式替换在脚本中包含换行符(因为标记了问题 重击)。它的工作原理是先将输入字符串每个字符分成一行,然后将每个字符插入保持缓冲区的开头。
x
交换保留空间和模式空间,然后H
H将(当前)模式空间附加到保持空间。因此,对于每个字符,我们将其放置到容纳空间中,然后将旧的容纳空间附加到其上,从而反转输入。最后的命令删除换行符以重建原始字符串。
这适用于任何单个字符串,但是它将多行输入连接为单个输出字符串。