文字列の最後の文字を削除したいので、この小さなスクリプトを試しました:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
しかし、それは「lkj」を出力します、私が間違っているのは何ですか?
文字列の最後の文字を削除したいので、この小さなスクリプトを試しました:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
しかし、それは「lkj」を出力します、私が間違っているのは何ですか?
回答:
POSIXシェルでは、構文${t:-2}
は何か異なることを意味します-if が設定されてnull以外の値に展開され、それ以外のt
場合t
はvalueに展開されます2
。パラメーターの展開によって1文字をトリムするには、おそらく必要な構文は${t%?}
in ksh93
、bash
or zsh
、${t:(-2)}
または${t: -2}
(スペースに注意)は部分文字列の展開としては有効ですが、末尾から2文字目の位置から始まる部分文字列を返す(つまり、最初の文字i
を削除するため)文字列ijk
)。
詳細については、Bashリファレンスマニュアルの「シェルパラメータ拡張」セクションを参照してください。
${parameter%word}
は、最短のサフィックスパターンマッチングを削除しますword
-のパラメーター拡張セクションを参照してくださいman bash
でbash
4.2以上、あなたが行うことができます。
${var::-1}
例:
$ a=123
$ echo "${a::-1}"
12
古いものbash
(bash 3.2.5
OS Xなど)の場合は、コロンの前後にスペースを入れてください:
${var: : -1}
bash
バージョン4.2-alpha以降で機能しますが、アクセスできるバージョンが以前のものよりも悪いです。:-/
${var:offset:lenght}
はのみに追加されましたbash 4.2
。たぶん、OSXは独自のパッチを追加しbash
ます。
ORをn
使用しない行から最後の文字を削除する場合: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
sedを使用すると、
sed 's/.$//'
その場合、単一のエコーはecho ljk | sed 's/.$//'
です。
これを使用すると、1行の文字列は任意のサイズになります。
シェルに応じたいくつかのオプション:
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=${t%?}
はBourne ではありませんが、最近ではBourneシェルに出くわすことはないでしょう。${t%?}
しかし、他のすべてで機能します。
fish
進行中の作業です。string
組み込みを導入した2.3.0 は、Q&Aの時点ではリリースされていません。私がテストしているバージョンでは、あなたは必要ですstring replace -r '(?s).\z' '' -- $t
(そして、彼らはそれを変更したいと思うでしょう、彼らはPCREに渡すフラグを変更するべきです)またはより複雑なもの。また、改行文字の処理が不十分であり、改行文字の変更も計画していることを知っています。
最もポータブルで最短の答えは、ほぼ確実です。
${t%?}
これは、bash、sh、ash、dash、busybox / ash、zsh、kshなどで機能します。
これは、旧式のシェルパラメータ拡張を使用して機能します。具体的には、globパターンに一致する%
パラメーターの最小一致サフィックス(つまり、任意の文字)を削除するように指定します。t
?
「最小のサフィックス・パターンを削除する」を参照してください。ここでは(多くの)のためのより多くの詳細な説明とより多くの背景を。man bash
「パラメータ展開」の下のシェルのドキュメントも参照してください(例:)。
サイドノートとして、代わりに最初の文字を削除する場合は、を使用します${t#?}
。これ#
は、後ろ(サフィックス)ではなく、文字列(プレフィックス)の前から一致するためです。
また、注目に値するの両方のことである%
と#
有する%%
と##
一致するバージョン、その最長の代わりに最短の所定のパターンのバージョン。ただし、この場合、両方の${t%%?}
and ${t##?}
は単一の演算子と同じように動作します(したがって、無駄な余分な文字を追加しないでください)。これは、指定された?
パターンが単一の文字にのみ一致するためです。*
いくつかの非ワイルドカードとa を混ぜると、andで物事がより面白く%%
なり##
ます。
パラメータ展開を理解すること、または少なくともその存在とその検索方法を知ることは、多くの種類のシェルスクリプトを記述および解読するのに非常に役立ちます。多くの人にとって、パラメーター展開はしばしば難解なシェルのブードゥーのように見えます。それは ...よく...それらは不可解なシェルのブードゥーだからです(ただし、「パラメーターの展開」を探すことを知っていれば、かなりよく文書化されています)。ただし、シェルで立ち往生しているときは、ツールベルトに入れておくと間違いありません。
またhead
、最後の文字以外のすべてを印刷するために使用できます。
$ s='i am a string'
$ news=$(echo -n $s | head -c -1)
$ echo $news
i am a strin
しかし、残念ながら一部のバージョンにhead
は先行-
オプションが含まれていません。これは、head
OS Xに付属しているものの場合です。
純粋な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/%\ /}'"
最初の構文は文字列から部分文字列を取ります。構文は
次のとおりです。2番目の構文では、符号に注意してください。
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
そして、上記の2つの短い形式があります
echo "Removed trailing whitespace: '${STR::-1}'"
echo "Removed trailing whitespace: '${STR%\ }'"
ここで再び%
記号に注目してください。これは、 'Remove(つまり、' 'で置換)最短一致パターン(ここではPARAMETERの末尾のエスケープされたスペース' \ 'で表されます -ここではSTRという名前)