web-dev-qa-db-ja.com

Bash-連続文字列操作

#!/bin/bash

FILE="$(basename "$1")"
FILE="${FILE/%.jpeg/.jpg}"

とにかく、これら2つの線を1つのライナーに接着する方法はありますか?

11
gsklee

FILE=$(basename "${1/%.jpeg/.jpg}")がうまくいきました。

テスト:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

スクリプトの内容:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"
12
Tim Kennedy

Bashで(zsh以外のksh、ash、その他のシェルで)拡張をネストすることはできません。これは表面的な制限にすぎません。説明するように、中間式を一時変数に割り当てることができるからです。ワンライナーの場合は少し面倒ですが、スクリプトでは読みやすさの点で間違いなく優れています。

外部ユーティリティbasenameの使用を避け、代わりに文字列操作構文を使用できます。

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

ここでは、スクリプトを コマンド置換を外側に配置 に書き換えることができます。それは一般的な現象ではなく、特定のワンライナー感以外のものも得られません。

Zshは、良くも悪くも、拡張をネストすることができます:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

または、basenameの代わりにzshの組み込み構造を使用することもできます。

FILE=${${1:t}/%.jpeg/.jpg}

私は行きます:

FILE=$(basename $1 .jpeg).jpg

Basenameの2番目のパラメーターは、ファイル名から削除するサフィックスです(man basenameを参照)。

4
Chirlo

次のように、単一のsedコマンドを使用できます。

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")
3
enzotib

sedを組み込むと、これでうまくいくはずです。

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(私は答えられないので、これはあなたの質問に正確には答えません。それが可能かどうかはわかりません。)

2
sr_

バッシュ${}コンストラクトは変数名で機能するため、コマンドを直接埋め込む方法はありません。 @sr_のアプローチは、余分なフォークを気にしない場合の代替手段です。

1
l0b0

この線

FILE=$(basename "${1/%.jpeg/.jpg}")

短縮してよりポータブルにすることができます

FILE=$(basename "${1%.jpeg}.jpg")
1