Bash-连续字符串操作


Answers:


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"

由于这两条线是可以互换的,所以到目前为止,这种解决方案是最整洁的...如果sed我猜这两条线不是可互换的,那肯定是需要的。
gsklee 2011年

11

您不能在bash中嵌套扩展(也不能在zsh之外的ksh,ash和其他shell中嵌套扩展)。这只是一个外观上的限制,因为正如您所说明的,您可以将中间表达式分配给临时变量。对于单行代码来说,这有点烦人,但是在脚本中,它的可读性可以说更好。

您可以避免使用外部实用程序,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的第二个参数是要从文件名中删除的后缀(请参阅参考资料man basename


3

您可以使用单个sed命令,如下所示:

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

2

合并sed,这应该可以解决问题:

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

(这不能完全回答您的问题,因为我不能;不知道是否可能。)


1

Bash ${}构造使用变量名,因此无法直接嵌入命令。如果您不介意使用额外的fork,则@sr_的方法是一种替代方法。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.