0

好的,我有很多文件都包含版本号 v1 或 v2。我想将文件名与作为第二个文件组成的其他文件匹配,如下所示:train.v1_GENENAME_ID.debruijn.txt(这就是我想要的)

第一个文件的组成如下:train.GENENAME_ID_v1.debruijn.txt

所以 v1 应该在 GENENAME 之前移动。所有版本标识符都是相同的。即v1或v2

假设我有一个名为:'train.Glis2_1757.2_v1_deBruijn.txt'并且我想将其转换为这个文件'train.v1_Glis2_1757.2_deBruijn.txt'

有没有一种简单的方法可以从第一个文件名中获取 v1 并将其放在第二个文件名中?

我正在考虑将 grep 与 if 语句结合使用。但仍然没有设法使它工作。

任何提示/提示表示赞赏。

4

3 回答 3

2

使用renameperl 分发:

rename 's/(train.)(.*_)(v[0-9].)(deBruijn.txt)/$1$3$2$4/' *

在某些系统上,它被称为“ren”或“pren”。

于 2013-04-22T14:28:43.900 回答
1

这是一个使用 for 循环并sed用于转换文件名的方法

for f in *.txt;
do
    nf=$(echo $f | sed -r 's/([^.]+\.)([^.]+\.)([0-9])_([^_]+)(.*)/\1\4_\2\3\5/')
    echo mv $f $nf
done

如果您对结果感到满意,您可以删除echo并让重命名发生

根据您的要求,这里是注释版本,解释了如何提取和重新排列各个部分以适应所需的输出

echo "train.Glis2_1757.2_v1_deBruijn.txt" | sed -r 
's/([^.]+\.) # match all non-dot characters (+ meaning one or more) followed by a dot and store in group 1 (train.)
   ([^.]+\.) # match all non-dot characters followed by a dot and store in group 2 (Glis2_1757.)
   ([0-9])   # match a single digit and store in group 3 (2)
   _         
   ([^_]+)   # match all non-underscore characters and store in group 4 (v1)
   (.*)      # match all that follow . is a wildcard char in regex and * is for zero or more (_deBruijn.txt)
/\1\4_\2\3\5/' # rearranging the matches to get desired output
于 2013-04-22T14:36:33.413 回答
1

您可以在 shell 中使用参数扩展执行此操作,特别是后缀和前缀删除:

FN=train.Glis2_1757.2_v1_deBruijn.txt
STRIPPED=${FN%_deBruijn.txt}                      # "train.Glis2_1757.2_v1"
GENEVERS=${STRIPPED#train.}                       # "Glis2_1757.2_v1"
VERSION=${GENEVERS##*_}                           # "v1"
GENENAME=${GENEVERS%_v[12]}                       # "Glis2_1757.2"

NEWFN=train.${VERSION}_${GENENAME}_deBruijn.txt   # "train.v1_Glis2_1757.2_deBruijn.txt"

mv $FN $NEWFN

您不必经历上述所有明确的命名步骤,但我认为这更清楚。此外,假设您可以用 shell 模式表示法表示它们,这种技术可以推断为具有任意前缀(“train.”除外)和后缀(“_deBruijn.txt”除外)。

于 2013-04-22T14:51:09.327 回答