如何反转shell字符串中的单词列表?

问题描述 投票:12回答:13

我有一个字符串中的单词列表:

str="SaaaaE SeeeeE SbbbbE SffffE SccccE"

我想扭转它以获得

"SccccE SffffE SbbbbE SeeeeE SaaaaE"

我怎么能用ash做到这一点?

linux shell awk sed ash
13个回答
18
投票

您可以使用awk如下:

echo "$str" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }'

0
投票

另一种纯粹的bash解决方案

sh

0
投票

如果要从文件中读取输入(如此处所示: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)为简单起见,可能省略了一些错误检查


0
投票

BASH

这是我使用的功能,(未在灰中测试)

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

0
投票

这是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来解决这个问题,可读性可能不是最受关注的问题。


12
投票

是的,您可以尝试这些命令,

对于字符串,

echo "aaaa eeee bbbb ffff cccc"|tr ' ' '\n'|tac|tr '\n' ' '

对于变量,

echo $str|tr ' ' '\n'|tac|tr '\n' ' '

6
投票

你可以使用awk:

echo "aaaa eeee bbbb ffff cccc" | awk '{for(i=NF;i>0;--i)printf "%s%s",$i,(i>1?OFS:ORS)}'

向后循环穿过字段,打印每个字段。 OFS是输出字段分隔符(默认为空格),ORS是输出记录分隔符(换行符)。

我假设你不希望每个单词中的字母顺序颠倒过来。


4
投票

这是使用awk dowhile(在Stackoverflow中没有太多使用) 没有额外的变量需要i

echo "aaaa eeee bbbb ffff cccc"|awk '{do printf "%s"(NF>1?FS:RS),$NF;while(--NF)}'
cccc ffff bbbb eeee aaaa

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 

1
投票

如果使用Haskell是可以接受的,那么有一个很好的工具叫做hawk(haskell-awk),可以很容易地做到这一点。首先你需要安装它:

$ cabal install haskell-awk

然后:

$ echo $str | hawk -m reverse

你需要在你的qazxsw poi中使用qazxsw poi找到qazxsw poi。


1
投票

但分组:

~/.cabal/bin

1
投票

这适用于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或复杂的替换操作。我最后得到了最后一个例子,因为它没有使用。


0
投票
reverse() {
    if [ "$#" -gt 0 ]; then
        local arg=$1
        shift
        reverse "$@"
        printf '%s\n' "$arg"
    fi
}

OUTPUT


****反转字符串的程序***


进入这里:我爱我的印度

你进入了:我爱我的印度

字符串的反向:印度我的爱我

© www.soinside.com 2019 - 2024. All rights reserved.