使用字符而不是位置提取子字符串

使用字符而不是位置提取子字符串

我最近开始使用 nautilus 脚本,对于我正在编写的脚本,我需要从文件名中提取子字符串。我的问题是我发现了很多方法来根据位置的字符,而不是任何关于如何在字符串中查找给定字符并从该字符或直到该字符提取子字符串的内容。

cut -f1 -d "delimiter"

有效,但cut仅接受 1 个字符分隔符。

也许awk或者expr

编辑:
我正在用 bash 编写,例如我期望一个具有以下名称的文件

[email protected]

简单地重命名为

Any Series S01 E01 VOSTFR.avi

答案1

对于 POSIX shell,使用模式剥离参数扩展运算符(最初来自 Korn shell):

string=whateverDELIMrestDELIMmore
before_first_DELIM=${string%%DELIM*}
before_last_DELIM=${string%DELIM*}
after_first_DELIM=${string#*DELIM}
after_last_DELIM=${string##*DELIM}

答案2

如果您已经写下了您希望如何使用此脚本,我将能够给出更具体的答案,但是我认为以下行可能足以让您适应您的需求。

$ echo "abcde" | awk '{print substr($0, index($0, "c"))}'
cde

只需将第二个参数替换index为您想要的字符即可。

答案3

参数扩展实际上起到了作用。

echo ${1%.S??E*}|sed 's/\./ /'

与系列名称相呼应,并将潜在的点改为空格。不适用于任何系列(例如机器人先生需要一个点),但是,这已经足够接近了。

答案4

您只提供了一个例子。更多的话就更好了!

[email protected]

你想分解成:

  • Any Series
  • S01
  • E01
  • VOSTFR
  • avi

乍一看,这与 RPM 包命名问题并没有太大不同,其中第一个字段(名称)可以包含其他地方使用的分隔符。但是,我假设您有一个固定格式字段,您还想将其分成两个字段。

为此,我会分开季节+剧集:

IFS=';' episode=( $(echo "$FILENAME"|sed -E 's/(.+)\.(S[0-9]{2})(E[0-9]{2})\.([^\.]+)\..*\.([^\.]+)/\1;\2;\3;\4;\5/') )

我将分配范围的分隔符设置为分号,然后将正则表达式的输出插入到 bash 数组中,该数组将有五个字段:${episode[0]} .. ${episode[4]}

我尚未将剧集名称字段点扩展为空格。我们可能可以一次性完成这一切,但是单独处理它可以让您执行诸如使用下划线之类的操作,或者添加复杂性,例如在->..的情况下查找 double 。简单地:Mr..RobotMr. Robot

episode[0]="${episode[0]//./ }"

更复杂的是,保留.它表示缩写的位置,如“ Mr. Robot”:

episode[0]="$(echo "${episode[0]}"|sed -E 's/\.([^\.])/ \1/g')"

最后,我将构造一个目标文件名,使用数组扩展打印字段 #0 中的四个字段,以空格分隔,然后是句点,然后是最后一个字段:

TARGET="${episode[@]:0:4}.${episode[4]}"

然后只需传递FILENAMEand TARGETto mv,使用引号是安全的:

mv "$FILENAME" "$TARGET"

相关内容