Bash-連続文字列操作


11
#!/bin/bash

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

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

回答:


12

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"

2つのラインは多少交換可能であるため、このソリューションはこれまでのところ最も近いものです...ラインが交換可能でない場合、sed間違いなく必要になると思います。
gsklee

11

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

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

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

4

私は行きます:

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

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


3

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

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

2

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

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

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


1

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.