%20%D0%B8%D0%BC%D0%B5%D0%BD%20%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D1%85%20%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D0%BD%D1%8B%20%D0%B2%20%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D0%BE%D0%BC%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B5%3F.png)
Мне нужно переместить сотни файлов, имена которых включают идентификационный номер, и эти номера перечислены построчно в текстовом файле.
Например:
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
А как насчет (если ваша оболочка обеспечивает «подстановку процесса»)
. <(sed 's/^/echo mv /; s/$/* \/target/' ID.txt)
Если результат вас устраивает, удалите эхо.
РЕДАКТИРОВАТЬ(предложено Стефаном Шазеласом)
sed 's|.*|mv -- &_* /target/|' ID.txt | sh -v -n
Удалите, -n
если результат вас устраивает.
решение2
Предполагая, что имена файлов не содержат пробелов, символов новой строки, обратных косых черт или кавычек, а также имея оболочку вроде ksh, zsh или bash с поддержкой подстановки процессов, вы можете сделать следующее:
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^
в начале каждой строки, чтобы число совпадало в начале строки, и_
в конце, чтобы a123
не соответствовало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