Você deve explicar como deseja renomear esses arquivos exatamente.
Totor 26/01
11
Bem, eu tenho arquivos com uma extensão de * .gappedPeak e quero renomeá-los para * .bed. todos eles estão no mesmo diretório que deve ser muito simples, mas um completo para o laço era necessário para me suceder
Sander Van der Zeeuw
O que você encontrou no Google se aplica ao MSDOS, eu acho.
tiktak
@devnull 's solução alternativa é realmente útil
lucasvw
Respostas:
22
Quando você emite o comando:
mv *.txt *.tsv
o shell, vamos assumir o bash, expande os curingas se houver algum arquivo correspondente (incluindo diretórios). A lista de arquivos é passada para o programa, aqui mv. Se nenhuma correspondência for encontrada, a versão não expandida será aprovada.
Novamente: o shell expande os padrões, não o programa.
Cargas de exemplos é talvez a melhor maneira, então vamos lá:
Exemplo 1:
$ ls
file1.txt file2.txt
$ mv *.txt *.tsv
Agora, o que acontece na mvlinha é que o shell se expande *.txtpara os arquivos correspondentes. Como não há *.tsvarquivos que não são alterados.
O mvcomando é chamado com dois argumentos especiais :
argc: Número de argumentos, incluindo o programa.
argv: Uma matriz de argumentos, incluindo o programa como primeira entrada.
O mvprograma verifica se o último argumento,, *.tsvé um diretório. Como não é, o programa não pode continuar, pois não foi projetado para concatenar arquivos. (Normalmente, mova todos os arquivos para um.) Nem crie diretórios por capricho.
Agora, novamente, mvverifique se *.tsvexiste. Como não, o arquivo file1.txté movido para *.tsv. Ou seja: o arquivo é renomeado para *.tsvcom o asterisco e tudo.
Como *.tsvagora é um diretório, os arquivos acabam sendo movidos para lá.
Agora: usando comandos como some_command *.tsvquando a intenção é realmente manter o curinga, deve-se sempre citá-lo. Ao citar, você evita que os curingas sejam expandidos se houver correspondências. Por exemplo, digamos mkdir "*.tsv".
Exemplo 4:
A expansão pode ser vista ainda mais se você fizer, por exemplo:
Agora: o mvcomando pode e funciona em vários arquivos. Mas se houver mais de dois, o último terá que ser um diretório de destino. (Opcionalmente, você pode usar a -t TARGET_DIRopção, pelo menos para GNU mv.)
Quanto aos seus links. Você forneceu um (em um comentário), onde mvnão é mencionado, mas rename. Se você tiver mais links, poderá compartilhar. Assim como nas páginas de manual em que você afirma que isso é expresso.
Sei que isso não responde à sua pergunta, mas, se você estava procurando outra maneira de renomear os arquivos em comparação com o loop da solução alternativa, por que não usar find? Eu usei esse comando várias vezes para substituir as extensões de arquivos em grandes diretórios por centenas de milhares de arquivos. Isso deve funcionar em qualquer sistema compatível com POSIX:
' .' => caminho de pesquisa começando no diretório atual marcado por '. "
-name=> define o nome da correspondência de localização (nesse caso, todos os arquivos que terminam com
.gappedPeak)
-exec => execute o seguinte comando em cada partida
sh -c => 'exec' cria um ambiente de shell independente para cada correspondência
mv "$1" "${1%.gappedPeak}.bed"=> mvprimeira variável (indicada por $ 1 ), que é o nome do arquivo atual, com o novo nome. Aqui eu faço uma correspondência de substring e apago; então pegue o primeiro var novamente, $ 1 e use %para excluir .gappedPeakda string. A .bedno final apenas encadeia a variável remanescente, que é agora apenas , com , criando o novo nome de ficheiro.test#.bedtest#.bed
O sublinhado é um espaço reservado por US $ 0
O {}é substituído por cada *.gappedPeaknome de arquivo ( ) encontrado pelo findcomando e se torna $ 1 no shcomando.
\;marca o final do -execcomando. Você também pode usar ';'ou ";".
Exemplo:
[user@before]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.gappedPeak
[user@after]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.bed
Você poderia passar pelo comando que descreve o que cada parte faz?
precisa saber é o seguinte
Sinto muito por isso, atualizei minha postagem. Espero que ajude.
precisa saber é
11
Incrível, obrigado! Com um guia do bash e sua explicação, consegui tudo.
precisa saber é o seguinte
Sem problemas. Ainda bem que ajuda.
devnull
Funciona como um encanto. Aqui está outro exemplo simplificado para file.abc-> blub.xyzem vários sub dirs:find . -name "file.abc" -exec sh -c 'mv "$1" "$(dirname $1)/blub.xyz"' _ {} \;
Mahn
9
mv *.txt *.tsvnão funciona; mvpode renomear apenas um arquivo por vez. Você entendeu mal as explicações ou elas estão erradas.
mmve renamepode renomear vários arquivos de uma vez. Mas existem duas versões em renametorno das quais são chamadas de maneira diferente. Deve haver muitas perguntas sobre isso aqui.
@SanderVanderZeeuw Embarrassing. Essas pessoas oferecem cursos? Infelizmente, não vejo a possibilidade de contato lá. Você pode verificar facilmente se isso funciona. Mas mv *.txt *.tsvmv(geralmente) não vê *.txtou *.tsvos nomes de arquivo expandidos pelo shell. O número de arquivos para os quais esses curingas se expandem seria "aleatório". A única situação em que isso funciona é se houver um arquivo com o nome *.txtque será renomeado para (literalmente) *.tsv(sem citar a bashopção nullglobnão deve ser configurada).
Hauke Laging
11
Ou pior. Se alguém tem um arquivo chamado por exemplo, foo.txte um chamado baz.tsva mv *.txt *.tsvirá substituir o existente .tsvarquivo ...
Runium
4
Por exemplo, se você tem asd.txte qwe.txtarquivos no diretório ao executar o comando mv *.txt *.tsv, ele tenta mover esses dois arquivos para um diretório chamado *.tsv. Como não existe esse diretório, ocorre um erro.
A primeira linha copia todos os *.txtarquivos para *.tsvpreservar seus atributos usando o -psinalizador.
A segunda linha remove todos os arquivos com o padrão *.txt
Este método requer que você tenha espaço em disco suficiente para armazenar temporariamente os arquivos de origem e de destino
Esse método é mais lento do mvque simplesmente altera o / directory / filename sem realmente mover os arquivos, a menos que estejam em uma partição diferente.
Respostas:
Quando você emite o comando:
o shell, vamos assumir o bash, expande os curingas se houver algum arquivo correspondente (incluindo diretórios). A lista de arquivos é passada para o programa, aqui
mv
. Se nenhuma correspondência for encontrada, a versão não expandida será aprovada.Novamente: o shell expande os padrões, não o programa.
Cargas de exemplos é talvez a melhor maneira, então vamos lá:
Exemplo 1:
Agora, o que acontece na
mv
linha é que o shell se expande*.txt
para os arquivos correspondentes. Como não há*.tsv
arquivos que não são alterados.O
mv
comando é chamado com dois argumentos especiais :argc
: Número de argumentos, incluindo o programa.argv
: Uma matriz de argumentos, incluindo o programa como primeira entrada.No exemplo acima, isso seria:
O
mv
programa verifica se o último argumento,,*.tsv
é um diretório. Como não é, o programa não pode continuar, pois não foi projetado para concatenar arquivos. (Normalmente, mova todos os arquivos para um.) Nem crie diretórios por capricho.Como resultado, ele interrompe e relata o erro:
Exemplo 2:
Agora, se você diz:
O
mv
comando é executado com:Agora, novamente,
mv
verifique se*.tsv
existe. Como não, o arquivofile1.txt
é movido para*.tsv
. Ou seja: o arquivo é renomeado para*.tsv
com o asterisco e tudo.Exemplo 3:
Se você disse:
O
mv
comando é executado com:Como
*.tsv
agora é um diretório, os arquivos acabam sendo movidos para lá.Agora: usando comandos como
some_command *.tsv
quando a intenção é realmente manter o curinga, deve-se sempre citá-lo. Ao citar, você evita que os curingas sejam expandidos se houver correspondências. Por exemplo, digamosmkdir "*.tsv"
.Exemplo 4:
A expansão pode ser vista ainda mais se você fizer, por exemplo:
Exemplo 5:
Agora: o
mv
comando pode e funciona em vários arquivos. Mas se houver mais de dois, o último terá que ser um diretório de destino. (Opcionalmente, você pode usar a-t TARGET_DIR
opção, pelo menos para GNU mv.)Então, tudo bem:
Aqui
mv
seria chamado com:e todos os arquivos acabam no diretório
foo
.Quanto aos seus links. Você forneceu um (em um comentário), onde
mv
não é mencionado, masrename
. Se você tiver mais links, poderá compartilhar. Assim como nas páginas de manual em que você afirma que isso é expresso.fonte
Sei que isso não responde à sua pergunta, mas, se você estava procurando outra maneira de renomear os arquivos em comparação com o loop da solução alternativa, por que não usar
find
? Eu usei esse comando várias vezes para substituir as extensões de arquivos em grandes diretórios por centenas de milhares de arquivos. Isso deve funcionar em qualquer sistema compatível com POSIX:Divisão de comando:
Exemplo:
fonte
file.abc
->blub.xyz
em vários sub dirs:find . -name "file.abc" -exec sh -c 'mv "$1" "$(dirname $1)/blub.xyz"' _ {} \;
mv *.txt *.tsv
não funciona;mv
pode renomear apenas um arquivo por vez. Você entendeu mal as explicações ou elas estão erradas.mmv
erename
pode renomear vários arquivos de uma vez. Mas existem duas versões emrename
torno das quais são chamadas de maneira diferente. Deve haver muitas perguntas sobre isso aqui.fonte
rename
, nãomv
.mv *.txt *.tsv
mv
(geralmente) não vê*.txt
ou*.tsv
os nomes de arquivo expandidos pelo shell. O número de arquivos para os quais esses curingas se expandem seria "aleatório". A única situação em que isso funciona é se houver um arquivo com o nome*.txt
que será renomeado para (literalmente)*.tsv
(sem citar abash
opçãonullglob
não deve ser configurada).foo.txt
e um chamadobaz.tsv
amv *.txt *.tsv
irá substituir o existente.tsv
arquivo ...Por exemplo, se você tem
asd.txt
eqwe.txt
arquivos no diretório ao executar o comandomv *.txt *.tsv
, ele tenta mover esses dois arquivos para um diretório chamado*.tsv
. Como não existe esse diretório, ocorre um erro.fonte
rename(1)
rename
é um script perl de Larry Wall, o criador do perl. Ele usa um regex Perl e opera no nome do arquivo.Instalação
Debian / Ubuntu
Se você precisar instalar
rename
no Debian / Ubuntu, poderá fazerfonte
Outra opção a considerar é usar:
*.txt
arquivos para*.tsv
preservar seus atributos usando o-p
sinalizador.*.txt
mv
que simplesmente altera o / directory / filename sem realmente mover os arquivos, a menos que estejam em uma partição diferente.fonte