文字列内の単語のリストがあります:
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; }'
はい、これらのコマンドを試すことができます
stringの場合、
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
は出力レコード区切り文字(改行)です。
各Wordの文字の順序を逆にしたくないと思います。
以下は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
純粋なシェルが必要で、外部ツールがない場合は、次のことを考慮してください。
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)と呼ばれるNiceツールがあります。最初にそれをインストールする必要があります:
$ cabal install haskell-awk
次に:
$ echo $str | hawk -m reverse
PATH
を見つけるには、hawk
に~/.cabal/bin
が必要です。
sedのグループ化:
str="SaaaaE SeeeeE SbbbbE SffffE SccccE"
echo $str | sed 's/\(.* \)\(.* \)\(.* \)\(.* \)\(.*\)/\5 \4\3\2\1/g'
これは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
や複雑な置換操作が好きではありません。終了しました。どちらも使用していないため、最後の例を使用してください。
これは私が使用する関数です(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' ' ';}
別の純粋なbashソリューション:
str='test a is this'; res=""; prev=""
while [ "$prev" != "$str" ]; do res="$res${str##* } "; prev="$str"; str="${str% *}"; done
/* 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
これは、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を使用している場合、可読性はおそらく最大の関心事ではありません。
入力をファイルから読み取る場合(ここでの質問: ファイルから行を読み取る )、次の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)一部のエラーチェックは、簡略化のために省略されている場合があります