如何反转 shell 字符串中的单词列表?
- 2024-11-14 08:29:00
- admin 原创
- 18
问题描述:
我有一个字符串中的单词列表:
str="SaaaaE SeeeeE SbbbbE SffffE SccccE"
我想逆转它,以便得到
"SccccE SffffE SbbbbE SeeeeE SaaaaE"
我怎样才能做到这一点ash
?
解决方案 1:
您可以按如下方式使用awk
:
echo "$str" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }'
解决方案 2:
是的,你可以尝试这些命令,
对于字符串,
echo "aaaa eeee bbbb ffff cccc"|tr ' ' '
'|tac|tr '
' ' '
对于变量
echo $str|tr ' ' '
'|tac|tr '
' ' '
解决方案 3:
如果你需要纯 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
解决方案 4:
对于那些想要一个简单而不复杂的单行解决方案的人来说,tac是最好的选择。这是我所知道的最简单的使用tac
命令替换的方法:
echo $(tac -s ' ' <<< $str)
解决方案 5:
您可以使用 awk:
echo "aaaa eeee bbbb ffff cccc" | awk '{for(i=NF;i>0;--i)printf "%s%s",$i,(i>1?OFS:ORS)}'
向后循环遍历字段,打印每个字段。OFS
是输出字段分隔符(默认为空格),ORS
是输出记录分隔符(换行符)。
我假设你不想颠倒每个单词中字母的顺序。
解决方案 6:
这里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
解决方案 7:
如果可以使用 Haskell,那么有一款名为 hawk (haskell-awk) 的好工具可以非常轻松地完成此操作。首先,您需要安装它:
$ cabal install haskell-awk
然后:
$ echo $str | hawk -m reverse
您需要~/.cabal/bin
在您的中PATH
找到hawk
。
解决方案 8:
这有效sh
(我没有,ash
所以无法验证):
reverse() {
for (( i = ${#*}; i > 0; i-- ))
{
echo ${!i}
}
}
像这样使用:
$ reversed=$(reverse foo bar baz)
$ echo $reversed
baz bar foo
这里有一些替代方案。首先,不使用 C 风格的方案for
:
reverse() {
while [ ${#*} -gt 0 ]
do
echo ${*: -1}
set -- "${@:1:$(($#-1))}"
done
}
下一个(来自这里)适用于替换不起作用的地方(例如在 Android 上)
reverse() {
if [ "$#" -gt 0 ]; then
local arg=$1
shift
reverse "$@"
printf '%s
' "$arg"
fi
}
我试图找到一种适用于 Android 脚本的解决方案,因为 Android 脚本sh
不喜欢 C 风格for
或复杂的替换操作。我最终选择了最后一个示例,因为它既不使用 C 风格也不使用复杂的替换操作。
解决方案 9:
sed 分组:
str="SaaaaE SeeeeE SbbbbE SffffE SccccE"
echo $str | sed 's/(.* )(.* )(.* )(.* )(.*)/ /g'
解决方案 10:
使用 awk 的解决方案do...while
在输入字符串为空时会抛出错误,而使用for
循环的某些 awk 解决方案在输入字符串为空时会打印一个空行。这比以前的 awk 解决方案略短,不存在--NF
POSIX 中未定义行为的问题,并且当输入为空字符串时不会抛出错误或打印空行:
$ echo "aaaa eeee bbbb ffff cccc" | awk '{i=NF;while(i)printf "%s",$i (i-->1?FS:RS)}'
cccc ffff bbbb eeee aaaa
解决方案 11:
/* 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
输出
* 反转字符串的程序
点击这里:我爱我的印度
您已输入:我爱我的印度
字符串的反向:印度我的爱我
解决方案 12:
另一个纯 bash 解决方案:
str='test a is this'; res=""; prev=""
while [ "$prev" != "$str" ]; do res="$res${str##* } "; prev="$str"; str="${str% *}"; done
解决方案 13:
如果要从文件中读取输入(如此处所问:从文件中反向读取行),我创建了以下 bash 脚本,该脚本以反向打印每行的单词而不改变文件的行顺序(例如,当读取中文中的 RTL 而不是 LTR 单词时,我需要这个):
#!/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}"
注意:
1)确保输入文件为 UNIX EOL 格式,否则每行的最后一个字可能会被截断
2)为了简单起见,可能省略了一些错误检查
解决方案 14:
这是对 GNU sed 手册中的“反转行字符”脚本的稍微改编:
#!/usr/bin/sed -f
# Skip lines without blanks
/[[:blank:]]/! b
# Embed line between newlines
s/^.*$/\n&\n/
# Reset the t flag
tx
# Label to jump to
:x
# Swap first and last word between newlines for three or more words
s/
([^[:blank:]][^[:blank:]]*) (.*) ([^[:blank:]][^[:blank:]]*)
/ \n\n /
# Jump to label if there was a change on the line
tx
# Swap first and last word between newlines for exactly two words
s/
([^[:blank:]][^[:blank:]]*) ([^[:blank:]][^[:blank:]]*)
/\n \n/
# Remove the newline markers
s/
//g
它做了一些假设,例如没有前导或尾随空格,所有单词都恰好由一个空格分隔。带有前导或尾随空格的行保持不变,而单词不是恰好由一个空格分隔的行将保留多余的空格,这可能不是所希望的。
该脚本应适用于任何符合 POSIX 标准的 sed 和基本正则表达式 (BRE)。使用 GNU sed 和扩展正则表达式 (ERE) 可提高可读性,例如
s/
(S+) (.*) (S+)
/
/
用于主要替换,但如果您首先使用 sed 来解决这个问题,那么可读性可能不是首要考虑的问题。
解决方案 15:
重击
这是我使用的功能(未在 ash 中测试)
#reverse_word_order
function rwo(){ tr ' ' '
'<<<"$@"|tac|tr '
' ' ';}
echo $(rwo 'Hello There I am You')
#based on https://stackoverflow.com/a/27703859/1153645
短跑
(在 bash 中也可以使用,但是有些人似乎不喜欢 echo)
rwo(){ echo "$*"|tr ' ' '
'|tac|tr '
' ' ';}
正如 0andriy 暗示的那样,我们可以打高尔夫球,(或者如果您的平台有tac
但没有tr
):
rwo(){ echo "$*"|tac -s " ";} #dash compatible
rwo(){ tac -s " "<<<"$@";} #bashism
解决方案 16:
echo "aaaa eeee bbbb ffff cccc" | xargs echo | xargs -n1 echo | tac | xargs echo
我几乎在所有事情上都使用 xargs。它可以将每个单词放在一行上-n1
,也可以将所有单词放回到一行上。
通过回显字符串来取消引用,以便下一个 xargs 将每个单词视为一个单词
将每个单词都回显到其自己的行上
反转行的顺序
再次将它们全部打印在一行上
tac
可能有参数可以替代这些步骤
解决方案 17:
反转字符串但是保留结束标记。
#!/bin/bash
#set -x
read -p "Enter a sentence: " sentence
myArray=( $sentence )
counter="${#myArray[@]}"
i=0
for word in "${myArray[@]}"
do
if [ $counter -lt 1 ]
then break
fi
reverseArray[$i]="${myArray[$counter-1]}"
letterCounter=0
while read -n 1 letter
do
if [ "$letter" == '?' ] || [ "$letter" == '!' ] || [ "$letter" == '.' ]
then
endmark="$letter"
reverseArray[$i]=$(echo "${reverseArray[$i]}" | head -c "$letterCounter")
fi
((letterCounter++))
done < <(echo "${reverseArray[$i]}")
((i++))
((counter--))
done
echo "${reverseArray[*]}$endmark"
exit
输入:你好,世界?
输出:世界你好?
解决方案 18:
例如,如果输入是“BASH is good”,则输出应该是
HSAB si doog
echo "Enter a String"
read text
#METHOD 1
echo -e "
$text" | re
下面给出了另一种反转字符串的
echo "Enter a String"
read text
#METHOD 2
i=$((length-1))
while [ $i -ge 0 ]
do
revstr=$revstr${text:$i:1}
i=$((i-1))
done
echo "$revstr"
如果要在单独的行中打印输出,您可以将以下内容添加到 echo 语句中:
#here "| fmt -w1" prints data in serparate lines
echo "$revstr" | fmt -w1
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件