%20de%20seus%20nomes%20de%20arquivo%20est%C3%A3o%20listadas%20em%20um%20arquivo%20de%20texto%3F.png)
Preciso mover centenas de arquivos cujo nome inclui um número de identificação e esses números estão listados linha por linha em um arquivo de texto.
Por exemplo:
The content of `ID.txt`:
1231245
1435466
3454656
3356646
Arquivos que preciso mover:
1231245_134.fasta
1231245_134.dna
1435466_345.fasta
1435466_345.dna
3454656_789.fasta
3454656_789.dna
3356646_104.fasta
3356646_104.dna
Responder1
Que tal (se o seu shell fornecer "substituição de processo")
. <(sed 's/^/echo mv /; s/$/* \/target/' ID.txt)
Remova o eco se estiver satisfeito com o resultado.
EDITAR(proposta por Stéphane Chazelas)
sed 's|.*|mv -- &_* /target/|' ID.txt | sh -v -n
Remova o -n
se estiver satisfeito com o resultado.
Responder2
Supondo que os nomes dos arquivos não contenham espaços em branco, novas linhas, barras invertidas ou aspas e um shell como ksh, zsh ou bash com suporte para substituição de processos, você poderia fazer:
join -t_ <(printf '%s\n' *_* | sort -t_ -k1,1) <(sort ID.txt) |
xargs sh -c 'exec mv -- "$@" /target' sh
Responder3
- Você pode fornecer
grep
o argumento-f FILE
para corresponder às expressões emFILE
, um por linha. ID.txt
precisa ser ligeiramente modificado porsed
para que corresponda exatamente ao que você deseja: a^
no início de cada linha para fazer com que o número corresponda ao início de uma linha e_
no final para que a123
não corresponda123123_
.ls -1
listará um arquivo por linha.xargs -I FOOBAR
substitui ocorrências de FOOBAR pela linha de entrada em vez de anexar a linha de entrada.
Então:
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
Responder4
Uma solução pura bash
:
while IFS= read -r p; do mv ${p}* /target; done < ID.txt
< ID.txt
dá o arquivo como entradawhile IFS= read -r p
pula pelas linhasmv ${p}* /target
mova todos os arquivos começando com o número do arquivo para o/target
diretório.
Você pode escrever echo
na frente do mv
comando para controlar quais comandos serão executados:
$ 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