Przenieś plik wiersza polecenia z długą ścieżką do katalogu bez powtarzania ścieżki do katalogu

16

Czy jest jakiś sposób wykonania mvpolecenia bez wpisania pełnej ścieżki w drugim argumencie?

Przykład:

mv my/file/that/has/a/really/long/path/foo.bar some_magic_operator_that_means_the_same_directory/foo.baz

Finbarr
źródło
1
Jest jakiś powód, dla którego nie możesz po prostu cdprzejść do katalogu, a mvstamtąd?
zpletan
Często w codziennej pracy wykonuję tego rodzaju polecenia w wielu katalogach. Często muszę wykonać kilka poleceń z danego katalogu nadrzędnego.
Finbarr
Jakoś znalazłem to używając !! (podwójne wykrzykniki) w terminalu używa do uruchomienia ostatniego wykonanego polecenia. Możesz także dodać parametry / tekst do ostatniego polecenia, ale nigdy nie próbowałeś zmieniać / usuwać tekstu z ostatniego polecenia. Spróbuj, a jeśli ci się powiedzie, upuszczę to jak odpowiedź. Powodzenia!
Geppettvs D'Constanzo

Odpowiedzi:

32

Możesz użyć rozszerzenia nawiasu klamrowego bash. To:

mv my/file/that/has/a/really/long/path/foo.{bar,baz}

rozwinie się w:

mv my/file/that/has/a/really/long/path/foo.bar my/file/that/has/a/really/long/path/foo.baz

a następnie mvjest uruchamiany z tymi dwoma argumentami. Zobacz http://wiki.bash-hackers.org/syntax/expansion/brace, aby uzyskać więcej informacji na temat rozwijania nawiasów klamrowych.

geirha
źródło
3
To wspaniale. Nie wiedziałem, że możesz to zrobić.
Finbarr
5

Jako alternatywę dla rozszerzenia nawiasów klamrowych możesz użyć funkcji rozszerzenia historii powłoki bash :

  • ! wprowadza rozszerzenie historii
  • # oznaczenie zdarzenia oznaczające bieżące polecenie
  • $ desygnator słowa odnoszący się do ostatniego argumentu

Możesz wykonać podstawienia w rozwinięciu, używając s/pattern/replacementskładni podobnej do sed, np

somecommand path/to/foo.bar !#$:s/.bar/.baz

Dawny.

$ mv -v somepath/Original/Dir3/SubDir1/foo.bar !#$:s/.bar/.baz
mv -v somepath/Original/Dir3/SubDir1/foo.bar somepath/Original/Dir3/SubDir1/foo.baz
'somepath/Original/Dir3/SubDir1/foo.bar' -> 'somepath/Original/Dir3/SubDir1/foo.baz'

Jeśli chcesz konkretnie ścieżkę (na przykład do mvpliku o zupełnie innej nazwie, której nie można łatwo uzyskać przez podstawienie), możesz użyć hmodyfikatora:

$ mv -v somepath/Original/Dir3/SubDir1/foo.baz !#$:h/baz.foo
mv -v somepath/Original/Dir3/SubDir1/foo.baz somepath/Original/Dir3/SubDir1/baz.foo
'somepath/Original/Dir3/SubDir1/foo.baz' -> 'somepath/Original/Dir3/SubDir1/baz.foo'

Aby readlinezapoznać się z innymi opcjami, w tym kombinacjami klawiszy umożliwiającymi wyrwanie ostatniego argumentu, zobacz Jak powtórzyć aktualnie wpisany parametr w konsoli bash?

steeldriver
źródło
2

Możesz spróbować:

pushd .
cd /really/long/directory/name/
mv whatever.1 whatever.2
popd
zpletan
źródło
2

Ze zmienną

  1. Zapisz katalog w zmiennej: `DIR=./really/long/path/
  2. użyj ruchu: mv "$DIR"foo.bar "$DIR"foo.bz

W jednej linii: DIR=./really/long/path/; mv "$DIR"foo.bar "$DIR"foo.bz


Zmiana katalogu

  1. Możesz także cdprzejść do katalogu, w którym chcesz pracować:cd ./really/long/path
  2. następnie zmień nazwę pliku: mv foo.bar foo.bz

W jednej linii: cd ./really/long/path && mv foo.bar foo.bz

Danjjl
źródło
1
ten drugi wygląda znajomo ;-)
zpletan
2
Najlepsze zastosowanie &&w ostatniej linijce. W przeciwnym razie, jeśli się cdnie powiedzie, mvzostanie uruchomiony w niewłaściwym katalogu, potencjalnie nadpisując plik. Z cd ./really/long/path && mv foo.bar foo.baz, mvzostanie uruchomiony tylko wtedy, gdy cduda się zmienić katalog.
geirha
-3

Możesz użyć aliasu, aby skrócić nazwę katalogu:

alias src='/directory/name/of/source'
alias dst='/directory/name/of/destination'
mv src dst
shantanu
źródło
1
-1 alias test='/var/log' ; cd testdaje -bash: cd: test: No such file or directory.
zpletan