文字列の最後の文字を削除したいので、次の小さなスクリプトを試しました。
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
しかし、それは「lkj」を出力します、私は間違っていますか?
POSIXシェルでは、構文${t:-2}
は別の意味を持ちます。t
が設定されていてnull以外の場合はt
の値に展開され、それ以外の場合は値2
に展開されます。パラメータ展開によって単一の文字をトリミングするには、おそらく必要な構文は${t%?}
です。
ksh93
、bash
またはzsh
、${t:(-2)}
または${t: -2}
(スペースに注意)は部分文字列として有効であることに注意してください。展開されますが、最後から2文字後の位置にある部分文字列を返すため(つまり、first文字i
文字列ijk
)。
詳細については、Bashリファレンスマニュアルのシェルパラメータ拡張セクションをご覧ください。
bash
4.2以降では、次のことができます。
${var::-1}
例:
$ a=123
$ echo "${a::-1}"
12
古いbash
(たとえば、bash 3.2.5
(OS Xの場合)、コロンの間とコロンの後にスペースを入れてください:
${var: : -1}
Sedを使用すると、
sed 's/.$//'
あなたのシングルechoはecho ljk | sed 's/.$//'
。
これを使用すると、1行の文字列は任意のサイズにすることができます。
n
OR sed
を使用しない行から最後のawk
文字を削除するため:
> echo lkj | rev | cut -c (n+1)- | rev
たとえば、最後の文字one character
を次のように削除できます。
> echo lkj | rev | cut -c 2- | rev
> lk
rev
マンページから:
説明
revユーティリティは、指定されたファイルを標準出力にコピーし、各行の文字の順序を逆にします。ファイルが指定されていない場合は、標準入力が読み取られます。
更新:
文字列の長さがわからない場合は、次のことを試してください。
$ x="lkj"
$ echo "${x%?}"
lk
シェルに応じたいくつかのオプション:
t=${t%?}
_t=`expr " $t" : ' \(.*\).'`
t=${t[1,-2]}
_t=${t:0:-1}
_t=${t:0:${#t}-1}
_t=${t/%?}
_t=${t/~(E).$/}
@ {t=$1} ~~ $t *?
_すべてが最後の文字を取り除くことになっていますが、一部の実装(マルチバイト文字をサポートしないもの)が最後のバイトを取り除くことに気付くでしょう(マルチバイトの場合、最後の文字が破損する可能性があります)。
expr
バリアントは、_$t
_が複数の改行文字で終了しないことを前提としています。結果の文字列が最終的に_0
_(または一部の実装では_000
_または_-0
_)になった場合も、ゼロ以外の終了ステータスを返します。文字列に無効な文字が含まれている場合も、予期しない結果が生じる可能性があります。
最も移植性があり、最も短い答えはほぼ確実です。
${t%?}
これは、bash、sh、ash、dash、busybox/ash、zsh、kshなどで機能します。
古い学校のシェルパラメーター展開を使用して動作します。具体的には、%
は、グロブパターン?
(つまり、任意の文字)に一致するパラメーターt
の最小一致サフィックスを削除することを指定します。
詳細な説明と背景については、「最小のサフィックスパターンの削除」 ここ を参照してください。また、「パラメータ展開」のシェルのドキュメント(例:man bash
)も参照してください。
補足として、代わりにfirst文字を削除したい場合は、${t#?}
を使用します。これは、#
が文字列の先頭から一致するためです(接頭辞)の代わりに(接尾辞)。
また、%
と#
の両方に%%
と##
のバージョンがあり、これらはバージョンの最長バージョン最短の代わりに与えられたパターン。ただし、${t%%?}
と${t##?}
はどちらも、この場合の単一の演算子と同じように機能します(不要な文字を追加しないでください)。これは、指定された?
パターンが単一の文字にのみ一致するためです。 *
といくつかの非ワイルドカードを組み合わせて、%%
と##
を使用すると、物事がより面白くなります。
パラメータ展開を理解すること、または少なくともそれらの存在を理解し、それらを調べる方法を知ることは、多くのフレーバーのシェルスクリプトを記述および解読するのに非常に役立ちます。多くの人にとって、パラメータ展開は多くの場合、難解なシェルブードゥー教のように見えます...ええと...それらが難解なシェルブードゥー教(ただし、「パラメーター展開")。ただし、シェルで立ち往生している場合は、ツールベルトに入れておくことをお勧めします。
t=lkj
echo ${t:0:${#t}-1}
0から文字列長-1までの部分文字列を取得します。ただし、この減算はbash固有であり、他のシェルでは機能しないことに注意してください。
たとえば、dash
は解析することさえできません
echo ${t:0:$(expr ${#t} - 1)}
たとえば、Ubuntuでは/bin/sh
はdash
です
head
を使用して、最後の文字を除くすべてを出力することもできます。
$ s='i am a string'
$ news=$(echo -n $s | head -c -1)
$ echo $news
i am a strin
ただし、残念ながら、head
の一部のバージョンには、先頭の-
オプションが含まれていません。これは、OS Xに付属するhead
の場合です。
正規表現を使用するのは簡単です。
n=2
echo "lkj" | sed "s/\(.*\).\{$n\}/\1/"
SteelDriverとNetworkerに感謝します!
文字列の長さがわからない場合は、次のことを試してください。
$ x="lkj"
$ echo "${x%?}"
lk
いくつかの改良。複数の文字を削除するには、複数の疑問符を追加できます。たとえば、変数から最後の2文字を削除するには:$SRC_IP_MSG
、次のものを使用できます。
SRC_IP_MSG=${SRC_IP_MSG%??}
純粋なbashのいくつかの可能な使用法を完了するために:
#!/bin/bash
# Testing substring removal
STR="Exemple string with trailing whitespace "
echo "'$STR'"
echo "Removed trailing whitespace: '${STR:0:${#STR}-1}'"
echo "Removed trailing whitespace: '${STR/%\ /}'"
最初の構文は文字列から部分文字列を取り、構文は${STRING:OFFSET:LENGTH}
2番目のものについては、%
記号。これは「行末から」を意味し、構文は${STRING/PATTERN/SUBSTITUTION}
そして、ここに上記の2つの短い形式があります
echo "Removed trailing whitespace: '${STR::-1}'"
echo "Removed trailing whitespace: '${STR%\ }'"
ここで再び%
記号、つまり「削除(つまり ''で置換)を意味しますshortest一致パターン(ここではエスケープスペースで表されます'\'[〜#〜]パラメータの最後から[〜#〜]-ここでは[〜#〜] str [〜#〜]
コマンドラインまたはシェルスクリプトでphpを使用することもできます。時々、外科的解析に役立ちます。
php -r "echo substr('Hello', 0, -1);"
// Output hell
配管あり:
echo "hello" | php -r "echo substr(trim(fgets(STDIN)), 0, -1);"
// Output hell