我有一个字符串中的单词列表:
str="SaaaaE SeeeeE SbbbbE SffffE SccccE"
我想扭转它以获得
"SccccE SffffE SbbbbE SeeeeE SaaaaE"
我怎么能用ash
做到这一点?
您可以使用awk
如下:
echo "$str" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }'
另一种纯粹的bash解决方案
sh
如果要从文件中读取输入(如此处所示:for
),我创建了以下bash脚本,该脚本反向打印每行的单词而不更改文件行的顺序(我需要这样做,例如在读取单词RTL时LTR在说中文等):
/* Shell script to reverse the Input String */
echo " **** Program to Reverse a String **** "
read -p " Enter Here : " text
echo "You have entered : " $text
echo -n "Reverse of String : "
arr=($text)
arrlength=${#arr[@]}
arrlength=`expr $arrlength - 1`
while [ $arrlength -ge 0 ]
do
echo -n ${arr[arrlength]}
echo -n " "
arrlength=`expr $arrlength - 1`
done
echo
笔记: 1)确保输入文件是UNIX EOL格式,否则可能会从每一行截断最后一个字 2)为简单起见,可能省略了一些错误检查
这是我使用的功能,(未在灰中测试)
str='test a is this'; res=""; prev=""
while [ "$prev" != "$str" ]; do res="$res${str##* } "; prev="$str"; str="${str% *}"; done
(也适用于bash,但有些人似乎厌恶回声)
read line reverse from a file
这是GNU sed手册中#!/bin/bash
fileName="$1"
outputFile="ReversedFile.npp"
echo > ${outputFile}
lineCount=`cat $fileName | wc -l`
for ((lineNum=1; ${lineNum} <= ${lineCount}; lineNum++))
do
echo
echo "Processing Line ${lineNum} of ${lineCount} ..."
lineOfFile="`cat $fileName | head -${lineNum} | tail -1`"
echo "${lineOfFile}"
rm -f wordFile.txt
for eachWord in `echo "${lineOfFile}"`
do
echo "${eachWord}" >> wordFile.txt
done
if [ -e wordFile.txt ]; then
thisLine=""
wordCount=`cat wordFile.txt| wc -l`
for ((wordNum=${wordCount}; ${wordNum}>=1; wordNum--))
do
wordOfLine="`cat wordFile.txt | head -${wordNum} | tail -1`"
echo "${wordNum} of ${wordCount} is ${wordOfLine}"
thisLine+="${wordOfLine} "
done
echo "output"
echo "${thisLine}"
echo "${thisLine}" >> ${outputFile}
rm -f wordFile.txt
fi
done
echo
echo "Output in File ${outputFile}"
脚本的略微改编:
#reverse_word_order
function rwo(){ tr ' ' '\n'<<<"$@"|tac|tr '\n' ' ';}
echo $(rwo 'Hello There I am You')
#based on https://stackoverflow.com/a/27703859/1153645
它做了一些假设,例如没有前导空格或尾随空格,所有单词只用一个空格分隔。带有前导或尾随空白的行保持不变,并且单词并非全部由一个空格分隔的行会留下多余的空格,这可能不是所期望的。
该脚本应该适用于任何符合POSIX标准的sed和基本正则表达式(BRE)。使用GNU sed和扩展正则表达式(ERE)可以提高可读性,例如
rwo(){ echo "$*"|tr ' ' '\n'|tac|tr '\n' ' ';}
对于主要的替代,但如果你首先使用sed来解决这个问题,可读性可能不是最受关注的问题。
是的,您可以尝试这些命令,
对于字符串,
echo "aaaa eeee bbbb ffff cccc"|tr ' ' '\n'|tac|tr '\n' ' '
对于变量,
echo $str|tr ' ' '\n'|tac|tr '\n' ' '
你可以使用awk:
echo "aaaa eeee bbbb ffff cccc" | awk '{for(i=NF;i>0;--i)printf "%s%s",$i,(i>1?OFS:ORS)}'
向后循环穿过字段,打印每个字段。 OFS
是输出字段分隔符(默认为空格),ORS
是输出记录分隔符(换行符)。
我假设你不希望每个单词中的字母顺序颠倒过来。
这是使用awk
do
的while
(在Stackoverflow中没有太多使用)
没有额外的变量需要i
echo "aaaa eeee bbbb ffff cccc"|awk '{do printf "%s"(NF>1?FS:RS),$NF;while(--NF)}'
cccc ffff bbbb eeee aaaa
如果你需要纯shell,没有外部工具,请考虑这个:
reverse_word_order() {
local result=
for word in $@; do
result="$word $result"
done
echo "$result"
}
reverse_word_order "$str"
否则tac
可以立即帮助您:
echo -n "$str" | tac -s' '
要么
tac -s' ' <<<"$str" | xargs
如果使用Haskell是可以接受的,那么有一个很好的工具叫做hawk(haskell-awk),可以很容易地做到这一点。首先你需要安装它:
$ cabal install haskell-awk
然后:
$ echo $str | hawk -m reverse
你需要在你的qazxsw poi中使用qazxsw poi找到qazxsw poi。
但分组:
~/.cabal/bin
这适用于PATH
(我没有hawk
所以无法验证):
str="SaaaaE SeeeeE SbbbbE SffffE SccccE"
echo $str | sed 's/\(.* \)\(.* \)\(.* \)\(.* \)\(.*\)/\5 \4\3\2\1/g'
像这样用它:
sh
这是一些替代方案。首先,一个不使用C风格的ash
:
reverse() {
for (( i = ${#*}; i > 0; i-- ))
{
echo ${!i}
}
}
下一个(来自$ reversed=$(reverse foo bar baz)
$ echo $reversed
baz bar foo
)适用于替换不适用的地方(例如在Android上)
for
我试图找到一个适用于Android脚本的解决方案,其中reverse() {
while [ ${#*} -gt 0 ]
do
echo ${*: -1}
set -- "${@:1:$(($#-1))}"
done
}
不喜欢C风格的here或复杂的替换操作。我最后得到了最后一个例子,因为它没有使用。
reverse() {
if [ "$#" -gt 0 ]; then
local arg=$1
shift
reverse "$@"
printf '%s\n' "$arg"
fi
}
OUTPUT
****反转字符串的程序***
进入这里:我爱我的印度
你进入了:我爱我的印度
字符串的反向:印度我的爱我