web-dev-qa-db-ja.com

シェル文字列の単語リストを逆にする方法は?

文字列内の単語のリストがあります:

str="SaaaaE SeeeeE SbbbbE SffffE SccccE"

取得するために逆にしたい

"SccccE SffffE SbbbbE SeeeeE SaaaaE"

ashを使用してどうすればよいですか?

16
MOHAMED

次のようにawkを使用できます。

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

はい、これらのコマンドを試すことができます

stringの場合、

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

変数の場合、

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

あなたはawkを使うことができます:

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

フィールドを逆方向にループして、それぞれを出力します。 OFSは出力フィールド区切り文字(デフォルトではスペース)であり、ORSは出力レコード区切り文字(改行)です。

各Wordの文字の順序を逆にしたくないと思います。

6
Tom Fenech

以下は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
4
Jotne

純粋なシェルが必要で、外部ツールがない場合は、次のことを考慮してください。

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
anandi

Haskellの使用が許容できる場合、これを非常に簡単に実行できるhawk(haskell-awk)と呼ばれるNiceツールがあります。最初にそれをインストールする必要があります:

$ cabal install haskell-awk

次に:

$ echo $str | hawk -m reverse

PATHを見つけるには、hawk~/.cabal/binが必要です。

2
Jens Petersen

sedのグループ化:

str="SaaaaE SeeeeE SbbbbE SffffE SccccE"

echo $str | sed 's/\(.* \)\(.* \)\(.* \)\(.* \)\(.*\)/\5 \4\3\2\1/g'
1
Aguevara

これは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
}

次のもの(from here )は、置換が機能しない場所で機能します(例:Android)

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

Androidスクリプトで機能する解決策を見つけようとしていましたが、shはCスタイルのforや複雑な置換操作が好きではありません。終了しました。どちらも使用していないため、最後の例を使用してください。

1
starfry

BASH

これは私が使用する関数です(ashでテストされていません)

#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

ダッシュ

(bashでも機能しますが、反響を嫌う人もいます)

rwo(){ echo "$*"|tr ' ' '\n'|tac|tr '\n' ' ';}
0
Alexx Roche

別の純粋なbashソリューション:

str='test a is this'; res=""; prev=""
while [ "$prev" != "$str" ]; do res="$res${str##* } "; prev="$str"; str="${str% *}"; done
0
Fabien Bouleau
/* 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

出力


****文字列を逆にするプログラム***


ここに入力してください:私は私のインドが大好きです

あなたが入力しました:私は私のインドが大好きです

文字列の逆:インド私の愛I

0
Bhupender Singh

これは、GNU sedマニュアルの 行の反転文字 スクリプトを少し変更したものです。

#!/usr/bin/sed -f

# Skip lines without blanks
/[[:blank:]]/! b

# Embed line between newlines
s/^.*$/\
&\
/

# Reset the t flag
tx

# Label to jump to
:x

# Swap first and last Word between newlines for three or more words
s/\n\([^[:blank:]][^[:blank:]]*\) \(.*\) \([^[:blank:]][^[:blank:]]*\)\n/\3 \
\2\
 \1/

# Jump to label if there was a change on the line
tx

# Swap first and last Word between newlines for exactly two words
s/\n\([^[:blank:]][^[:blank:]]*\) \([^[:blank:]][^[:blank:]]*\)\n/\2\
 \
\1/

# Remove the newline markers
s/\n//g

先頭または末尾に空白がなく、すべての単語が1つのスペースで区切られているなど、いくつかの前提条件があります。先頭または末尾に空白がある行は変更されずに残り、単語がすべて1つのスペースで区切られていない行は余分なスペースを残しますが、これは望ましいものではない可能性があります。

スクリプトは、POSIX準拠のsedおよび基本正規表現(BRE)で動作する必要があります。 GNU sedおよび拡張正規表現(ERE)を使用すると、次のように読みやすくなります。

s/\n(\S+) (.*) (\S+)\n/\3 \n\2\n \1/

主な置換の代わりに、最初にこの問題にsedを使用している場合、可読性はおそらく最大の関心事ではありません。

0
Benjamin W.

入力をファイルから読み取る場合(ここでの質問: ファイルから行を読み取る )、次のbashスクリプトを作成して、行の順序を変更せずに各行の単語を逆に出力しますファイル(たとえば、中国語などでLTRではなくRTLの単語を読み取る場合に必要です):

#!/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形式であることを確認してください。そうでない場合、最後のWordが各行から切り捨てられる可能性があります
2)一部のエラーチェックは、簡略化のために省略されている場合があります

0
harshvchawla