В bash, как я могу переименовать файл без повторения пути? [Дубликат]

39

Возможное дублирование:
повторное использование текста в команде bash

Если я хочу переименовать файл на несколько каталогов, как мне избежать повторения пути?

Например:

mv path/to/old_filename.txt path/to/new_filename.txt

Мне интересно, есть ли способ сделать это:

mv path/to/old_filename.txt (?)new_filename.txt

Где (?)бы был какой-то способ сказать "в том же каталоге".

Натан Лонг
источник

Ответы:

26

Использование расширения истории bash :

mv path/to/oldfile !#:1:h/newfile

где !#:1:hозначает: из строки, которую вы сейчас набираете ("! #"), возьмите первое слово (": 1"), а затем возьмите только компонент пути (": h" - заголовок) из него.

Гленн Джекман
источник
Это наиболее близко к тому, что предполагал исходный вопросник, и полезно знать, так что +1.
crazy2be
2
Круто! Я думаю, что метод расширения скобки Дарта проще, но это именно то, о чем я просил.
Натан Лонг
Сегодня я узнал две замечательные вещи. Кроме того, я всегда буду думать о расширении фигурной скобки как о «расширении фигурной скобки Дарта», потому что это звучит потрясающе.
PileOfMush
62

Вы можете использовать расширение скобки: mv path/to/{old_filename.txt,new_filename.txt}

Вот ссылка на руководство GNU по расширению скобок в оболочке bash, которое определяет список замен и говорит bash повторять параметр, используя разные замены каждый раз, когда повторяется.

Например,

a{b,c,dd,e}

будет расширен до

ab ac add ae

Единственное предостережение в том, что расширенные повторения должны быть в состоянии следовать друг за другом в качестве аргументов целевой программы.

Дарт Андроид
источник
5
Или сводя это к минимуму mv path/to/{old,new}_filename.txt. Это также помогает отмене или другим видам, близким к повторению команды. Я много раз делал, например mv /etc/X11/xorg.conf{,.backup}, возможность изменить процесс простым изменением mv /etc/X11/xorg.conf{.backup,}.
Даниэль Андерссон
26

Ответ Дарта выше умный, но если вы хотите использовать подход с cd, вы могли бы также рассмотреть возможность использования подоболочки:

(cd path/to && mv old_filename.txt new_filename.txt)

Поскольку изменение каталога происходит в подоболочке, вы фактически не будете изменять каталоги в своей интерактивной оболочке.

MLC
источник
1
Существенный недостаток: Вы не можете использовать табуляцию для old_filename.txt.
Bluenote10
9

Другая полезная альтернатива, если вы собираетесь выполнять несколько команд в каталоге, это:

pushd /path/to
mv oldfile newfile
...
popd
KeithB
источник
5

Мне нравится ответ @ Дарта . Вот альтернатива:cd path/to && mv oldfile newfile && cd -

Гленн Джекман
источник
1
Обратите внимание, что если mvне удается (например, нет разрешений), вы останетесь в path/toкаталоге. Вы можете cd path/to && mv oldfile newfile ; cd -убедиться, что cd -он всегда запущен, за исключением случаев, когда cd path/to(без прав доступа) произойдет сбой, вы все равно будете выполнять cd -и переходить к предыдущему каталогу, который является нежелательным. MLC (+1) subhell ответ лучше. Я полагаю, cd . && cd path/to && mv oldfile newfile ; cd -что это сработает в 99,9% случаев (с cd .ошибкой только в том случае, если вы или ваши текущие права доступа к каталогам изменились; и в этом случае переход на другой
каталог