[解決済み】Bashで文字列から最後のn文字を削除する方法は?
質問
私は、変数
var
のような文字列を保持するBashスクリプトの中にあります。
echo $var
"some string.rtf"
この文字列の最後の4文字を削除して、その結果を新しい変数に代入したい。
var2
というように
echo $var2
"some string"
どうすればいいのでしょうか?
どのように解決するのですか?
まず、通常は意図を明示したほうがよいでしょう。つまり、文字列の末尾が
.rtf
を削除したい場合、その
.rtf
を使えばいいのです。
var2=${var%.rtf}
. この方法の有用な点の1つは、もし文字列
がない場合
で終わる。
.rtf
の場合、全く変更されません。
var2
の変更されていないコピーが含まれます。
var
.
ファイル名のサフィックスを削除したいが、それが何であるかを正確に知らない、あるいは気にしない場合は、次のようにします。
var2=${var%.*}
で始まるものをすべて削除するには、最後の
.
. を含まないものだけを残しておきたい場合は、以下のようになります。
最初
.
を使用することができます。
var2=${var%%.*}
. これらのオプションは、1つの
.
しかし、複数ある場合は、文字列のどの端から作業するかを選択することになります。一方、もし
.
という文字列があります。
var2
は、またしても変更されない
var
.
もし、本当に特定の 番号 という文字が含まれている場合、以下のような選択肢があります。
あなたはこのようなタグを付けました。
bash
ということで、まずはbashのビルトインから。一番長く使えているのは、上で使ったのと同じサフィックス除去の構文で、4文字を除去するには
var2=${var%????}
. または、4文字のうち最初の1文字がドットの場合のみ削除する場合は
var2=${var%.???}
のようなものです。
var2=${var%.*}
が、ドット以降の部分がちょうど3文字である場合にのみサフィックスを削除する。この方法で文字を数えるには、未知の文字を1つ削除するごとにクエスチョンマークが1つ必要になるので、部分文字列の長さが大きくなるとこの方法は扱いづらくなります。
新しいバージョンのシェルでは、部分文字列抽出というオプションがあります。
var2=${var:0:${#var}-4}
. の代わりに任意の数字を入れることができます。
4
を使えば、異なる文字数を削除することができます。このとき
${#var}
は文字列の長さに置き換えられるので、これは実際には最初の文字(インデックス0)から始まる(長さ-4)文字を抽出して保持するように要求していることになります。この方法では、文字列がパターンにマッチする場合にのみ変更を加えるというオプションがなくなります。文字列の実際の値が何であろうと、コピーには最後の4文字以外が含まれることになります。
開始インデックスは省略可能で、デフォルトでは 0 になっています。
var2=${var::${#var}-4}
. 実際、新しいバージョンのbash(特に4以降、つまりMacOSに同梱されているものは動作しない)は、負の長さを、文字列の終わりから数えて停止する文字のインデックスとして認識します。そのため、これらのバージョンでは、文字列の長さを表す式を取り除くことができます。
var2=${var::-4}
.
bashではなく、他のPOSIX系シェルを使っている場合、パターンベースのサフィックス除去で
%
インデックスベースの部分文字列抽出ができない、古いダッシュでもです。Ksh と zsh は部分文字列抽出をサポートしていますが、明示的な 0 の開始インデックスを必要とします; zsh は負の終了インデックスもサポートしていますが、ksh は length 式を必要とします。zshは
配列
1から始まるが、それにもかかわらず
文字列
0から始まる
このbash互換の構文を使用する場合
. しかし、zsh ではスカラーパラメータを文字の配列のように扱うこともできます。この場合、部分文字列構文は 1 ベースのカウントを使用し、開始位置と (含む) 終了位置をカンマで区切った括弧内に配置します。
var2=$var[1,-5]
.
シェルに組み込まれたパラメータ展開を使う代わりに、もちろん何らかのユーティリティ・プログラムを実行して文字列を修正し、その出力をコマンド置換で取り込むことができます。動作するコマンドはいくつかあり、そのひとつが
var2=$(sed 's/.\{4\}$//' <<<"$var")
.
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み] Bashでコマンドの出力に変数を設定するにはどうすればよいですか?
-
[解決済み] Bashでファイルの中身をループする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 -bash: 予期しないトークン「改行」付近での構文エラー
-
[解決済み] バッシュ Vim.NET」が表示されたらVimを終了させる Warning: 出力先が端末でない"
-
[解決済み] Bashで文字列から改行を削除する方法
-
[解決済み] Docker ubuntu イメージ - bash: man: コマンドが見つかりません。
-
[解決済み] etc/profileでVISIBLE=NOWを設定するのはなぜですか?
-
[解決済み] bash スクリプトの "${BASH_SOURCE[0]}" と $( cd $( dirname "xxx" && pwd )) の意味について
-
[解決済み] echoコマンドでパイピングが効かない [重複]。
-
[解決済み] Bashを使ってプログレスインジケータを表示する [重複]。
-
[解決済み] Bashで部分文字列を抽出する
-
[解決済み】シェル変数に引用符で囲むのはいつ?