我需要移动数百个文件,其名称中包含 ID 号,并且这些号码在文本文件中逐行列出。
例如:
The content of `ID.txt`:
1231245
1435466
3454656
3356646
我需要移动的文件:
1231245_134.fasta
1231245_134.dna
1435466_345.fasta
1435466_345.dna
3454656_789.fasta
3454656_789.dna
3356646_104.fasta
3356646_104.dna
答案1
怎么样(如果你的 shell 提供“进程替换”)
. <(sed 's/^/echo mv /; s/$/* \/target/' ID.txt)
如果对结果满意,请删除回声。
编辑(由斯特凡·查泽拉斯提议)
sed 's|.*|mv -- &_* /target/|' ID.txt | sh -v -n
-n
如果对结果满意,请删除。
答案2
假设文件名不包含空格、换行符、反斜杠或引号,并且像 ksh、zsh 或 bash 这样的 shell 支持进程替换,您可以这样做:
join -t_ <(printf '%s\n' *_* | sort -t_ -k1,1) <(sort ID.txt) |
xargs sh -c 'exec mv -- "$@" /target' sh
答案3
- 您可以提供与 中的表达式匹配的
grep
参数,每行一个。-f FILE
FILE
ID.txt
需要稍微修改一下,sed
以便它只完全匹配您想要的内容:^
每行开头的 a 以使数字匹配行开头的数字,而_
在末尾的数字则不123
匹配123123_
。ls -1
每行将列出一个文件。xargs -I FOOBAR
用输入行替换出现的 FOOBAR,而不是附加输入行。
所以:
sed -e 's/^/^/' -e 's/$/_/' /path/to/ID.txt > /tmp/ID_regexp.txt
cd /old/dir
ls -1 | grep -f /tmp/ID_regexp.txt | xargs -I FILE mv FILE /new/dir
答案4
纯bash
解:
while IFS= read -r p; do mv ${p}* /target; done < ID.txt
< ID.txt
将文件作为输入while IFS= read -r p
穿过线路mv ${p}* /target
将文件中以编号开头的所有文件移动到/target
目录中。
您可以echo
在命令前面写入mv
来控制将执行哪些命令:
$ while IFS= read -r p; do echo mv ${p}* /target; done < ID.txt
mv 1231245_134.dna 1231245_134.fasta /target
mv 1435466_345.dna 1435466_345.fasta /target
mv 3454656_789.dna 3454656_789.fasta /target
mv 3356646_104.dna 3356646_104.fasta /target