Como posso mover centenas de arquivos cuja palavra-chave (ID) de seus nomes de arquivos está listada em um arquivo de texto?

0

Eu preciso mover centenas de arquivos cujo nome inclui um número de identificação e esses números sã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

Eu sou um iniciante em comandos unix. Eu imagino o que eu quero fazer é simples com uma linha de comandos combinando cat , xargs e find . No entanto, fiquei preso aqui por um tempo.

    
por Yuee Wang 28.08.2018 / 06:32

4 respostas

1

Que tal (se o seu shell fornece "substituição de processo")

. <(sed 's/^/echo mv /; s/$/* \/target/' ID.txt)

Remova o eco se estiver satisfeito com o resultado.

EDIT (proposto por Stéphane Chazelas)

sed 's|.*|mv -- &_* /target/|' ID.txt | sh -v -n

Remova o -n se estiver satisfeito com o resultado.

    
por 28.08.2018 / 11:08
1

Supondo que os nomes dos arquivos não contenham espaços em branco, novas linhas, barras invertidas ou aspas, e um shell como o 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
    
por 28.08.2018 / 11:55
1
  • Você pode atribuir grep ao argumento -f FILE para corresponder às expressões em FILE , uma por linha.
  • ID.txt precisa ser modificado levemente em sed para que corresponda exatamente ao que você deseja: um ^ no início de cada linha para fazer o número corresponder no início de uma linha e _ no início termine para que 123 não corresponda a 123123_ .
  • ls -1 listará um arquivo por linha.
  • xargs -I FOOBAR substitui as 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
    
por 28.08.2018 / 07:05
0

Uma solução bash pura:

while IFS= read -r p; do mv ${p}* /target; done < ID.txt
  • < ID.txt fornece o arquivo como entrada
  • while IFS= read -r p llops através das linhas
    • mv ${p}* /target move todos os arquivos que começam com o número no arquivo para o diretório /target .

Você pode escrever echo na frente do comando mv para controlar quais comandos seriam 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
    
por 28.08.2018 / 08:32

Tags