回答:
awk '{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//'
それでもすべての空白行に空行が出力されます。それを避けるには:
awk 'NF{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//;/./!d'
sed -n 's/.*[[:blank:]]\+\([^[:blank:]]\+\)[[:blank:]]*$/\1/p'
。
.*
たぶん最後尾だけでもよいでしょう-とにかく、末尾の空白以外は除外します.*[^[:blank:]]
。
awk
変数が$NF
あるすべてのレコードの最後のフィールド。これを使用して、次のようにファイルの最後のフィールドのみを印刷できます。
awk '{print $NF}' file
あと少しです。最後の単語を指定するだけです:
sed 's/^.* \([^ ][^ ]*\)/\1/g'
それがすること:
(より良いソリューションを追加するために編集。Hildredに感謝!)
sed -r 's/.* ([^ ]+)/\1/g'
拡張正規表現が許可されている場合は、通常そうです。
sed 's/.* //'
たとえば、のgrep
代わりにの適切なパターンを使用できsed
ます。
grep -o "[a-Z0-9]*$"
この例では[...]
、「単語」に適していると考えられる文字の範囲が含まれています(この場合は英数字、他の記号を追加できますが、一部はエスケープする必要があります)。
a-Z
ASCIIベースのロケールであっても、範囲はあまり意味がありません。これ-o
はGNU拡張機能であることに注意してください。
単語を修飾して1つ以上の非空白文字のシーケンスを意味する場合、答えは間違いなくあり、それも非常に簡単に行われます。これは、[[:blank:]]*
と[^[:blank:]]*
はブール値の補完であり、文字列内のすべての文字が完全な場合、[[:blank:]]*
U [^[:blank:]]*
は可能な文字列をほとんど同じ方法で記述できるため.*
です。
不完全な文字やその他の無効なバイトシーケンスが文字列内に存在する場合、文字列を誤ったエンコーディングで解釈する場合に発生する可能性があるように、先頭から最後まで正常に記述できません。文字列のバイトごとに完全な文字を確保するには、Cロケールを次のように強制できます。
LC_ALL=C sed ...
... .*
またはなどの包括的なパターンで頭から尾まで文字列を記述する問題を回避します([ ]*[^ ]*)*
完全に相補的なパターンは、文字列の長さを左から右に必要なだけ繰り返すことができ、パターンが途切れることなく最後に発生する可能性のある場所に到達します。これは間違いなく通常の言語です。
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*/\2/'
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*/\2/'
これらのバージョンはどちらも空白行を印刷します。これは、Kleene *
スターがパターンの0回以上の出現に一致するためです。最初に0個以上の空白でない文字に一致し、次に0個以上の空白文字に一致し、次に文字列全体に一致するまで、グループ化された一致の0個以上に一致します。
このすべてを一致したので、魔法が交換に起こる-参照はグループによって返される\1
と\2
、それぞれの最後に出現しています。そのため、置換が行われると、すべての文字列は、ゼロ以上の空白文字ではない行の最後の出現のみ、またはサブグループに置き換えられ\2
ます。
もちろん、これはすべての可能な文字列(空の文字列でも)に対して機能します。つまり、両方のフォームが空白文字のみを含むか、まったく含まない行の改行文字を印刷します。これを処理するためにできることは2つありますが、最初に文字クラスを少し入力しやすくします。
b='[:blank:]'
ここで、行に空白ではない文字が1つ以上含まれている場合にのみ印刷するには、次のようにします。
sed -n "s/\(\([^$b]*\)[$b]*\)*/\2/;/./p"
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*/\2/p"
構文が正しい限り、どちらの形式でもどちらの方法でも機能します。
-n
パターンスペースのスイッチを無効にし、自動印刷、p
にフラグs///
ubstitutionまたは/
アドレス/
コマンドは、成功した場合、その結果を印刷します。
これと同じロジックを適用して、{num}
次のような任意の発生を取得することもできます。
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*/\2/p"
sed -En "s/([$b]*([^$b]+)){num}.*/\2/p"
... num
両方の正規表現のを数字で置き換えると、{num}
空白文字ではない一連の指定されたオカレンスのみを出力できます。ここでは、文字列の先頭のスペースがカウントされないように、少し異なる形式が使用されています。
なお-E
へEREスイッチsed
、それはないですが、BSDやGNUバージョンの両方でサポートされてい POSIX標準の構文。
sed
実装(Solaris / usr / bin / sedなど)では機能せず、より単純なアプローチ(25行を超える入力行でメモリを使い果たす)よりも高価になることに注意してください。sed_su3
例えば家宝toolchestから)。だから、私は答えが好きですが、私はそのアプローチを勧めません。
s/.* \([^[:blank:]]\{1,\}\).*/\1/
がはるかに優れていますが、複数の行が関係している場合はさらに困難です。しかし、つい先日、私はそれ's/\(\n\)*/\1/g;s/\n\(\n.*\)*/&&/[num];s///[samenum]
をかなり効果的に補強できることを発見しました。とにかく、ロジックに明白なエラーがない限り、私は満足しています-私は何かを逃したに違いないと思いました。
sed
s について-それは少し変です-それは標準に従って健全でなければなりません。xratは言います... 標準の開発者は、特定の実装の"\n*"
"\n\{min,max\}", "\(...\)*"
"\(...\)\{min,max\}"
( '*' )
または区間式(項目(5)を参照)のために、後方参照によって参照される部分式が複数の文字列と一致する場合、後方参照は最後の(右端の)これらの文字列の。私はこれをw /でテストしたと確信してminised
います- minised
とにかく、私は先日w /変なものをテストしていました。
はい。次のsedコマンドは、最初にすべての末尾の空白(s/ *$//
)を削除してから、最後の空白(s/.* //
)までをすべて削除します。[[:blank:]]
タブやその他のスペースのような文字をキャプチャするために、リテラルの空白を置き換えることはおそらく価値があります。
$ echo " aaa bbb cc " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo " aaa bbb cc" | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "aaa bbb cc " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "aaa bbb cc" | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo " cc " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "cc" | sed -e 's/ *$//' -e 's/.* //'
cc
sed
か?