Como executo comandos em outra pasta, sem repetir o caminho da pasta?

72

Existe uma maneira inteligente de copiar e mover operações ou um comando para duplicar um arquivo, sem ter que fazer cd , então mv depois, na mesma pasta?

Por exemplo, tenho que executar o seguinte:

mv /folder1/folder2/folder3/file.txt /folder1/folder2/folder3/file-2013.txt

Note que o diretório para onde eu estou movendo o arquivo é o mesmo, mas eu tenho que colocar todo o caminho novamente e às vezes fica irritante. Estou curioso para saber se há outra maneira de fazer isso sem ter que colocar todo o caminho novamente , porque a operação seria feita no mesmo caminho.

    
por Valter Silva 17.05.2013 / 14:22

6 respostas

124

Basta usar a expansão de chaves :

mv /folder1/folder2/folder3/{file.txt,file-2013.txt}

Isso é equivalente a escrever:

mv /folder1/folder2/folder3/file.txt /folder1/folder2/folder3/file-2013.txt

A expansão de chave permite fornecer mais argumentos, é claro. Você pode até passar intervalos a ele, por exemplo para criar algumas pastas de teste, você pode executar mkdir test_{a..z} e, a partir do Bash 4, também é possível criar sequências com preenchimento zero, como em touch foo{0001..3} , que cria foo0001 , foo0002 e foo0003 . O Wiki do Bash Hackers tem um artigo com alguns exemplos para você.

Se você precisar usar dois comandos diferentes, use um subshell e cd primeiro, como na resposta de Ignacio .

    
por 17.05.2013 / 14:29
74

Execute a operação em um subshell.

( cd /folder1/folder2/folder3 && mv file.txt file-2013.txt )

A alteração do diretório de trabalho não será propagada para o shell pai.

    
por 17.05.2013 / 14:24
21

Se você quiser inteligente, aqui está o expansão do histórico

do bash
mv /folder1/folder2/folder3/file.txt !#:1:h/file-2013.txt

Eu não usaria isso sozinho, pois acho impossível memorizar. Eu ocasionalmente uso o equivalente vim , mas tenho que procurá-lo quase todas as vezes.     

por 17.05.2013 / 15:26
11

Você pode definir uma variável. Claro que isso tem o efeito colateral de deixar as variáveis por aí.

D=/folder1/folder2/folder3; mv $D/file.txt $D/file-2013.txt
    
por 17.05.2013 / 20:01
2

Eu gosto das outras soluções, mas aqui está outra, implementada como um script com matrizes bash, pushd, popd:

#!/bin/bash
set -e
# from http://stackoverflow.com/a/246128/178651
script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# paths relative to the script
relative_paths=( \
path1 \
path2 \
path3 \
path4
)

for relative_path in "${relative_paths[@]}"
do
  pushd "$script_path/$relative_path" > /dev/null 2>&1
  pwd
  mv filename1 filename2
  # could do other stuff in this directory...
  popd > /dev/null 2>&1
done

pushd "$script_path" > /dev/null 2>&1
# could do other stuff in same directory as script...
popd > /dev/null 2>&1
    
por 17.05.2013 / 22:30
1

Slhck responde diretamente a pergunta da maneira mais simples possível, mas Valter também gosta da resposta de autopop, então aqui está uma que está na mesma linha;

pushd /folder1/folder2/folder3/; mv file.txt file-2013.txt; popd
    
por 22.05.2013 / 00:29