4

この場合、「貪欲な」正規表現がどのように機能するかを理解していないと思うので、文の最初と最後の単語の順序を切り替えるために sed を使用しようとしています。私はたった3語の文章で惨めに失敗しました。

$ echo hello world mike | sed 's/\([a-z]*\).* \([a-z]*\).*/\2 \1/'
mike hello

出力が「world hello mike」ではないのはなぜですか? 役立つかもしれないいくつかの追加情報。

  1. \1 \2 は 1 番目と 2 番目の正規表現の一致です

  2. ここでチュートリアルに従っていました。

私の最終的な目標は、そこに単語がいくつあるかに関係なく、文の最初と最後の単語の順序を入れ替えることです。

4

7 に答える 7

7

パーツをキャプチャ グループの 1 つとして含めhelloていないため、出力されません。試す:

$ sed -E 's/([a-z]+) (.+) ([a-z]+)/\3 \2 \1/' <<< "hello world mike"
mike world hello
$ sed -E 's/([a-z]+) (.+) ([a-z]+)/\3 \2 \1/' <<< "hello world foo bar baz mike"
mike world foo bar baz hello

(注: echo の無駄な使用も削除しました。)

[a-z][[:alpha:]]大文字に置き換えることもできます。

$ sed -E 's/([[:alpha:]]+) (.+) ([[:alpha:]]+)/\3 \2 \1/' <<< "Hello world Mike"
Mike world Hello
于 2013-10-18T22:41:33.673 に答える
3

awkバージョン

echo hello world mike | awk '{s=$1;$1=$NF;$NF=s}1'
mike world hello

最後に提出されたものと最初に提出されたものを交換するだけでうまくいくはずです。

于 2013-10-18T22:46:23.657 に答える
2
$ echo "hello world mike" | sed -r 's/([^ ]+)(.* )([^ ]+)/\3\2\1/'
mike world hello
$ echo "this is a simple sentence" | sed -r 's/([^ ]+)(.+ )([^ ]+)/\3\2\1/'
sentence is a simple this

または、ERE ではなく BRE のみをサポートする古い sed:

$ echo "hello world mike" | sed 's/\([^ ]*\)\(.* \)\([^ ]*\)/\3\2\1/'
mike world hello
$ echo "this is a simple sentence" | sed 's/\([^ ]*\)\(.* \)\([^ ]*\)/\3\2\1/'
sentence is a simple this
于 2013-10-19T02:47:52.767 に答える
1

単語境界のある sed コマンド:

sed 's/\([A-Za-z]\+\)\(.\+\)\b\([A-Za-z]\+\)/\3\2\1/'

または拡張モード:

sed -r 's/([A-Za-z]+)(.+)\b([A-Za-z]+)/\3\2\1/'
于 2013-10-18T23:08:12.457 に答える
1

行の最初と最後の単語を交換するように求めているため、それらを確実にキャプチャする必要があります (上記の回答の多くがそうであるように、最初と 2 番目の単語ではありません)。

echo "hello cruel and unkind world" | sed 's/^\([^ ]*\) \(.*\) \([^ ]*\)$/\3 \2 \1/'

結果として

world cruel and unkind hello

仕組みは次のとおりです。

^\([^ ]*\)  - starting at the beginning of the line (^), find as many non-space characters as you can (stops at first space)
              note - depending on the flavor of sed you use, there are special symbols to map "a non whitespace, e.g. \S
            - the next space is matched but not captured
\(.*\)      - capture "everything" after this, until...
 \([^ ]*\)$ - a space followed by all non-space characters followed by the end of string

次に、3 つのキャプチャ グループを逆の順序で出力し、その間にスペースを入れると、求めていたものが正確に得られます。

于 2013-10-18T22:59:22.013 に答える
1

を使用 :

$ echo 'hello world mike' | awk '{v1=$1;v2=$NF;$1=$NF="";print v2, $0, v1}'
mike  world  hello
于 2013-10-18T22:43:02.507 に答える
0

split()より強力な言語のような別のアプローチを使用しますが、 の場合は、すべてのコンテンツを両方のエッジ ワードの間にグループ化する必要があります。

echo hello world mike | sed 's/\([a-z]*\)\(.*\) \([a-z]*\).*/\3\2 \1/'

次の結果が得られます。

mike world hello
于 2013-10-18T22:41:20.683 に答える