根据另一个文件内容的完全匹配重命名文件名的一部分

时间:2014-06-05 22:16:45

标签: linux sed rename file-rename mv

我想通过仅更改文件名的一部分来重命名一堆文件,并根据另一个文件中列表中的完全匹配来执行此操作。例如,如果我有这些文件名:

sample_ACGTA.txt
sample_ACGTA.fq.abc
sample_ACGT.txt
sample_TTTTTC.tsv
sample_ACCCGGG.fq
sample_ACCCGGG.txt
otherfile.txt

我希望根据这些完全匹配找到并替换,这些匹配位于另一个名为replacements.txt的文件中:

ACGT    name1
TTTTTC  longername12
ACCCGGG nam7
ACGTA   another4

这样所需的结果文件名就是

sample_another4.txt
sample_another4.fq.abc
sample_name1.txt
sample_longername12.tsv
sample_nam7.fq
sample_nam7.txt
otherfile.txt

我不想改变内容。到目前为止,我已根据此网站上的搜索结果尝试了sedmv。使用sed我找到了如何使用我的列表替换文件的内容:

while read from to; do
  sed -i "s/$from/$to/" infile ;
done < replacements.txt, 

mv我找到了一种方法来重命名文件,如果有一个简单的替换:

for files in sample_*; do
  mv "$files" "${files/ACGTA/another4}"
done 

但是我怎么能把它们放在一起做我想做的事呢?

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您可以使用awk生成命令:

% awk '{print "for files in sample_*; do mv $files ${files/" $1 "/" $2 "}; done" }' replacements.txt 
for files in sample_*; do mv $files ${files/ACGT/name1}; done
for files in sample_*; do mv $files ${files/TTTTTC/longername12}; done
for files in sample_*; do mv $files ${files/ACCCGGG/nam7}; done
for files in sample_*; do mv $files ${files/ACGTA/another4}; done

然后将输出复制/粘贴或直接传输到shell:

% awk '{print "for files in sample_*; do mv $files ${files/" $1 "/" $2 "}; done" }' replacements.txt | bash

如果您希望首先使用较长的匹配字符串,请先对替换项进行排序:

% sort -r replacements.txt | awk '{print "for files in sample_*; do mv $files ${files/" $1 "/" $2 "}; done" }' | bash

答案 1 :(得分:0)

您可以完美地将forwhile循环合并为仅使用mv

while read from to ; do
  for i in test* ; do
    if [ "$i" != "${i/$from/$to}" ] ; then
      mv $i ${i/$from/$to}
    fi
  done
done < replacements.txt

使用sed的替代解决方案可能包括使用执行替换结果的e命令(谨慎使用!首先尝试不使用结尾e来打印命令被执行)。

因此:

sed 's/\(\w\+\)\s\+\(\w\+\)/mv sample_\1\.txt sample_\2\.txt/e' replacements.txt

将解析您的replacements.txt文件并根据需要重命名所有.txt文件。

我们只需要添加一个循环来处理其他扩展:

for j in .txt .bak .tsv .fq .fq.abc ; do
  sed "s/\(\w\+\)\s\+\(\w\+\)/mv 'sample_\1$j' 'sample_\2$j'/e" replacements.txt
done

(请注意,在尝试重命名不存在的文件时,您应该收到错误消息,例如,当它尝试执行mv sample_ACGT.fq sample_name1.fq但文件sample_ACGT.fq不存在时)