首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在文件名中找到一个具有常量和正则表达式的字符串,并替换它。

在文件名中找到一个具有常量和正则表达式的字符串,并替换它。
EN

Stack Overflow用户
提问于 2022-08-12 13:22:47
回答 2查看 44关注 0票数 0

我觉得这是个蹩脚的问题,但经过多次尝试,我被困住了。我有很多这样的文件:

代码语言:javascript
复制
S2EC1_DKDL220005480-2a-AK13554-7UDI265_HHJ2MCCX2_L8_1.fq.gz
S2EC1_DKDL220005480-2a-AK13554-7UDI265_HHJ2MCCX2_L8_2.fq.gz
S2EC2_DKDL220005480-2a-5UDI249-7UDI265_HHJ2MCCX2_L8_1.fq.gz
S2EC2_DKDL220005480-2a-5UDI249-7UDI265_HHJ2MCCX2_L8_2.fq.gz
S2EC11_DKDL220005480-2a-5UDI251-5UDI1063_HHJ2MCCX2_L8_1.fq.gz
S2EC11_DKDL220005480-2a-5UDI251-5UDI1063_HHJ2MCCX2_L8_2.fq.gz

我试着把它们重命名如下:

代码语言:javascript
复制
S2EC1_R1.fastq.gz
S2EC1_R2.fastq.gz
S2EC2_R1.fastq.gz
S2EC2_R2.fastq.gz
S2EC11_R1.fastq.gz
S2EC11_R2.fastq.gz

文件名是可变长度。在每个文件名、DKDL220005480-2a-_HHJ2MCCX2_L8中都有相同的位,但中间的位是中间的一点,在组合和长度上是可变的。

从bash shell中,我可以以一种分步的方式取得一些进展,通过这样做可以消除常量文本:

代码语言:javascript
复制
for x in *; do mv $x ${x/DKDL220005480-2a-/}; done
for x in *; do mv $x ${x/_HHJ2MCCX2_L8_/_R}; done

它产生的文件名如下:

代码语言:javascript
复制
S2EC1_AK13554-7UDI265_R1.fq.gz
S2EC1_AK13554-7UDI265_R2.fq.gz
S2EC2_5UDI249-7UDI265_R1.fq.gz
S2EC2_5UDI249-7UDI265_R2.fq.gz
S2EC11_5UDI251-5UDI1063_R1.fq.gz
S2EC11_5UDI251-5UDI1063_R2.fq.gz

但现在我没能找到并替换中间的可变部分。当然,一蹴而就也要优雅得多。

下面是我认为最有希望匹配可变中间位的代码:

代码语言:javascript
复制
for x in *; do mv $x ${x/_(.+)_/}; done

但我知道这个错误:

代码语言:javascript
复制
mv: 'S2EC1_AK13554-7UDI265_R1.fq.gz' and 'S2EC1_AK13554-7UDI265_R1.fq.gz' are the same file
mv: 'S2EC1_AK13554-7UDI265_R2.fq.gz' and 'S2EC1_AK13554-7UDI265_R2.fq.gz' are the same file
mv: 'S2EC2_5UDI249-7UDI265_R1.fq.gz' and 'S2EC2_5UDI249-7UDI265_R1.fq.gz' are the same file
mv: 'S2EC2_5UDI249-7UDI265_R2.fq.gz' and 'S2EC2_5UDI249-7UDI265_R2.fq.gz' are the same file
mv: 'S2EC11_5UDI251-5UDI1063_R1.fq.gz' and 'S2EC11_5UDI251-5UDI1063_R1.fq.gz' are the same file
mv: 'S2EC11_5UDI251-5UDI1063_R2.fq.gz' and 'S2EC11_5UDI251-5UDI1063_R2.fq.gz' are the same file

不确定我的正则表达式或mv代码是否有问题(或者两者都有,甚至可能有其他问题,哈哈)。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-12 13:38:37

模式匹配和正则表达式是两件不同的事情。在模式匹配中,*表示任何字符串。在正则表达式中,它指的是前面的零或多个。在模式匹配中,(.+)意味着..。文字(.+)字符串。在正则表达式中,它表示至少一个字符的捕获组。

对于简单的重命名方案,您可以尝试:

代码语言:javascript
复制
for f in *.fq.gz; do
  g="${f/_DKDL220005480-2a-*_HHJ2MCCX2_L8_/_R}"
  printf 'mv "%s" "%s"\n' "$f" "${g%.fq.gz}.fastq.gz"
#  mv "$f" "${g%.fq.gz}.fastq.gz"
done

对输出满意后,取消对mv行的注释。

票数 1
EN

Stack Overflow用户

发布于 2022-08-12 19:13:03

要在bash中使用正则表达式,需要使用[[ $x =~ regex ]],可以在$BASH_REMATCH中使用组,因此:

代码语言:javascript
复制
for x in *; do
    [[ $x =~ ^(S2EC[0-9]+)_.*_([0-9]+).fq.gz$ ]] &&
        mv $x ${BASH_REMATCH[1]}_R${BASH_REMATCH[2]}.fastq.gz
done
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73334877

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档