文字列の最後の3文字だけを出力するコマンド

文字列の最後の3文字だけを出力するコマンド

このコマンドは文字列のcut最初の文字を印刷できることを知っていますが、最後の文字を選択する方法は?nn

可変数の文字を含む文字列がある場合、文字列の最後の3文字だけを印刷するにはどうすればよいですか?例えば。

希望の「無限」出力は「ted」です。
「987654」の所望の出力は「654」である。
「123456789」に必要な出力は「789」です。

答え1

なぜ誰も明確な答えを持っていないのですか?

sed 's/.*\(...\)/\1/'

...または少し明確ではありません

grep -o '...$'

もちろん、2番目は3文字未満の行が消えるという欠点がありますが、この質問はこの場合の動作を明確に定義しません。

答え2

簡単に保つ - 尾

文字数を計算するために正規表現や複数のプロセスは必要ありません。
このコマンドは、tail最後の項目を表示するためによく使用されます。ワイヤーファイルには、これを行うのに適したツールと思われるオプション-c()があります。--bytes

$ printf 123456789 | tail -c 3
789

(シェルにいるときは起動プロセスを保存するので、mikeservの答えにあるメソッドを使用するのが合理的ですtail。)

実際のUnicode文字?

さて、最後の3つを尋ねます。数値;この答えはそうではありません。最後の3つを出力します。バイト

各文字がバイトであればtail -c大丈夫です。したがって、文字セットがある限り使用できます。ASCIIISO 8859-1または変形。

通常、Unicode入力がある場合UTF-8誤った形式、誤った結果:

$ printf 123αβγ | tail -c 3
�γ

この例では、UTF-8ギリシャ文字のアルファ、ベータ、ガンマを使用して長さが2バイトです。

$ printf 123αβγ | wc -c  
9

このオプションは、-m少なくとも実際のUnicode文字数を計算します。

printf 123αβγ | wc -m
6

いいですね。最後の6バイトは最後の3文字を提供します。

$ printf 123αβγ | tail -c 6
αβγ

したがって、tail一般的な文字処理はサポートされておらず、試してもしません(下記参照)。可変サイズ行は処理しますが、可変サイズ文字は処理しません。

このように表現してみましょう。tail解決しようとしている問題の構造には合いますが、データ型には適していません。

GNUコアツール

sed詳しくは、GNU coreutils(、、、、lsなどtailの基本的なツールバーcut)はまだ完全に国際化されていません。主にUnicodeをサポートしています。
たとえば、cutここで文字をサポートするためにtailの代わりにtailを使用するのは良い選択です。これにはバイトまたは文字-c((--bytes)および-m--chars)処理オプションがあります。

ちょうど-m/ 2013バージョン--chars以来実装されていません!
cut (GNU coreutils) 8.21

からinfo cut

`-c CHARACTER-LIST'
`--characters=CHARACTER-LIST'
     Select for printing only the characters in positions listed in CHARACTER-LIST.  
     The same as `-b' for now, but internationalization will change that.


これも見てください回答到着UTF-8で `cut -c`(`--characters`)を使用できませんか?

答え3

テキストが名前付きシェル変数にある場合、またはシェルでこれを行うことSTRINGができます。bashzshmkshbusybox ash

printf '%s\n' "${STRING:(-3)}"

または

printf '%s\n' "${STRING: -3}"

この構文のソースksh93と組み合わせて使用​​することもお勧めします。

要点は、:を と分離しなければならないということです。それ以外の場合は、Bourne シェル演算子-になります。${var:-default}

zshまたは、シェルの対応する構文は次yashのとおりです。

printf '%s\n' "${STRING[-3,-1]}"

答え4

文字列が変数にある場合は、次のことができます。

printf %s\\n "${var#"${var%???}"}"

これにより、like値から最後の3文字が削除されます$var

${var%???}

...その後、頭から$varすべてを削除します。しかし、削除したばかりの内容は次のとおりです。

${var#"${var%???}"}

このアプローチには長所と短所があります。利点は、完全にPOSIX移植可能であり、すべての最新のシェルで動作することです。また、$var3文字以上含まれていない場合何もないただし、末尾の\n行が印刷されます。それからまた、考えるこの場合、印刷には次の追加手順が必要です。

last3=${var#"${var%???}"}
printf %s\\n "${last3:-$var}"

これにより、3バイト以下の場合にのみ空になります$last3$varそして空の場合$varにのみ置き換えられます。または、設定したばかりではないことを知っています。$last3$last3unsetunset

関連情報