Bash:重新定位字符串中的子字符串

时间:2016-05-10 09:21:40

标签: regex bash unix awk sed

我有一些我想重命名的文件。文件名如下所示:

C18-02B-NEB-sktrim_1-20000000.fq
C18-02B-NEB-sktrim_1-30000000.fq
C18-02B-NEB-sktrim_1-50000000.fq
C18-02B-NEB-sktrim_2-20000000.fq
C18-02B-NEB-sktrim_2-30000000.fq
...

我想将_digit部分重新定位到.fq之前,就像这样。

C18-02B-NEB-sktrim-20000000_1.fq
C18-02B-NEB-sktrim-30000000_1.fq
C18-02B-NEB-sktrim-50000000_1.fq
C18-02B-NEB-sktrim-20000000_2.fq
C18-02B-NEB-sktrim-30000000_2.fq
...

我能够捕获我感兴趣的子串:

find  * | egrep -o '_[0-9]'
_1
_1
_1
_2
_2

我也可以从字符串中删除子字符串:

find  * | sed 's/_[0-9]//'
C18-02B-NEB-sktrim-20000000.fq
C18-02B-NEB-sktrim-30000000.fq
C18-02B-NEB-sktrim-50000000.fq
C18-02B-NEB-sktrim-20000000.fq

但我不知道如何将其移至新位置,然后重命名文件。

3 个答案:

答案 0 :(得分:2)

使用捕获组,例如:

 sed 's/\(.*\)sktrim\(_[0-9]*\)\(.*\)\.fq/\1sktrim\3\2.fg/'

rename perl实用程序可以将此sed表达式和一组文件转换为一组对应的mv。 由于这些重命名生成的mv将在系统级别(他们不会启动/bin/mv,而只是使用rename(2)系统功能)它&#39 ;比使用生成自己的mv命令并从shell启动它们更快。

答案 1 :(得分:1)

这应该这样做:

find . -name '*.fq' -exec sh -c 'mv "$0" "$(echo "$0" |sed "s/^\(.*\)\(_[0-9]\)\(.*\)\.fq$/\1\3\2.fq/")"' {} \;

sed部分:

sed "s/^\(.*\)\(_[0-9]\)\(.*\)\.fq$/\1\3\2.fq/"

说明:

find . -name '*.fq'搜索glob模式*.fq,然后-exec选项对找到的每个文件执行mv命令。

sh -c 'mv "$0" "$var"' {}构造只是一个带有两个参数的mv命令,$0{}替换,findrnm -rs '/^(.*)(_\d)(.*)\.fq$/\1\3\2.fq/' *.fq 找到的文件名

<小时/> 如果您想要文件重命名,那么最好使用专门用于文件重命名的工具。重命名是一个非常流行的工具,但我有自己的工具:rnm

使用rnm,您可以执行以下操作:

sed

或使用完全相同的正则表达式,如rnm --regex basic -rs '/^\(.*\)\(_[0-9]\)\(.*\)\.fq$/\1\3\2.fq/' *.fq 命令(即BRE):

destination : Be my friend today
source      : good
position    : 6

答案 2 :(得分:0)

使用rename

rename 's/sktrim(_\d+)(.*)\.fq/sktrim$2$1.fq/' *.fq