Файл mv з довгою назвою

У Linux я іноді перейменую такі файли:

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

Зауважте, що я хочу просто перейменувати файл, а не перемістити його в інший каталог.

Чи є команда, яка дозволить мені зробити скорочену версію цієї команди? Я маю на увазі:

mv dir1/dir2/dir3/file.txt  file.txt.old

або навіть щось подібне (щоб просто додати назву):

mv dir1/dir2/dir3/file.txt  {}.old

Моя мета - не повторювати повний шлях.

Я знаю, що ті «приклади», які я написав, не працюють, але це лише уявлення про те, що я хочу зробити.

Я не хочу вводити в каталог.

19
Ніхто не сказав, що потрібно змінити інший каталог, тільки той, який ви хочете.
додано Автор Michael Hampton, джерело
Чому ви не перейдете до каталогу? Це швидко і вирішує вашу проблему.
додано Автор Michael Hampton, джерело
Зауважте, що (cd dir1/dir2/dir3 && exec mv file.txt {,. Old}) має фактично таку ж продуктивність, що й код без підпроцесу, оскільки exec уникає fork() під час виклику зовнішньої команди, тому ви маєте рівно одну вилку.
додано Автор Charles Duffy, джерело
Я маю справу з багатьма підкаталогами з цього самого місця
додано Автор Bernhard, джерело

7 Відповіді

для одного файлу

mv dir1/dir2/dir3/file.{txt,txt.old}

де конструкція X {a, b} розширюється на Xa Xb , ви можете мати попередній перегляд

echo dir1/dir2/dir3/file.{txt,txt.old}

щоб побачити, чи відповідає вона вашим потребам.

Примітка:

  1. that for multiple files

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

навряд чи розшириться до того, що ви хочете. (це буде розширено до змішаного файлу file.txt file1.txt.old file2.txt ...)

  1. {txt,txt.old} can be shorterned to {,.old} as per comment

  2. if directory name are unambigous, wildcard can be used.

    mv *1/*2/d*/*.{,old}
    

for multiple file use rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

введіть -n , щоб мати ефективне перейменування.

44
додано
@santiagoarizti ці трюки прийшли в довгостроковій перспективі, деякі через такий форум (разом з U&L, SU, AskUbuntu ...), а іноді й уважно читаючи сторінки (спеціально довгі, такі як bash або awk ). Щоб бути зрозумілим, я знайшов тут трюки, і я знаходжу трюк, який читає людина.
додано Автор Moz, джерело
@Josh Так він працює відмінно і вимагає менше натискань на клавіші. Я використовую цю конструкцію дуже регулярно.
додано Автор Guest, джерело
це смішно, як ви можете використовувати Linux оболонку протягом багатьох років і все ще знаходите нові трюки весь час
додано Автор Bernhard, джерело
Думаю, всі ці «трюки» були б більш очевидними, якби я пройшов формальну підготовку з баш-мови, але я тільки навчався достатньо для того, щоб просунутися.
додано Автор Bernhard, джерело
Приємно, я не знав цього шляху розширення! спасибі
додано Автор Bernhard, джерело
Чи не працюватиме mv dir1/dir2/dir3/file.txt {,. Old} , і чи буде ще коротше?
додано Автор Christopher Creutzig, джерело

Команда rename перейменовує всі відповідні файли. Її основною метою є перейменування декількох файлів, але якщо вираз Perl відповідає тільки одному файлу, то він перейменує тільки цей один файл. Для отримання докладніших відомостей та специфічного синтаксису дистрибутиву прочитайте manpage: man rename .

Приклад використання: перейменуйте "/path/file.txt" у "/path/file.txt.old":

rename 's/file.txt/file.txt.old/g' /path/file.txt

Коротші позначення (завдяки шаломбі):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

Для сухого виконання використовуйте rename -n .

More examples and details can be found at https://thepcspy.com/read/bulk-rename-files-in-ubuntu/

6
додано
На жаль, різні дистрибутиви Linux мають різні команди rename з зовсім іншою поведінкою.
додано Автор kasperd, джерело
@ Fabian - я не був дрочил, тільки прагнучи до "найкоротшої руки" за те, що, здається, часто використовується ідіома, який шукає ОП:)
додано Автор shalomb, джерело
Для цього конкретного завдання перейменування додаванням .old до імені файлу, це, мабуть, трохи зручніше зробити rename 's/$ /. txt або rename '$ _. = ". old"' /path/to/file.txt
додано Автор shalomb, джерело
круто, я знав про команду перейменування, просто не знав, що все може зробити, дякую!
додано Автор Bernhard, джерело

Мені подобається рішення @ archemar про використання {} розширення, тому що ви можете використовувати його, коли ви вже запустили свій командний рядок. Ось деякі інші можливості для повноти:

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(котирування потрібні, лише якщо у назві є пробіли або інші символи, які розбивають слово)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

Примітки:

  • This is bash syntax, you might be using another shell
  • mymv can be any reasonable string, I used mymv for "my move".
  • The function definition can be put in your .bash_profile

Інший:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

але

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(від @Adam та @CharlesDuffy), можливо, краще у випадку збою компакт-диска.

4
додано
Не використовуйте mmv , програма вже названа таким чином.
додано Автор glglgl, джерело
@glglgl Done:
додано Автор Law29, джерело

Для одноразового випадку, якщо я не хочу змінювати свій поточний каталог, я можу просто використовувати під-оболонку:

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

Тому що ви cd всередині під-оболонки, ви не змінили ваш каталог у вашій фактичній оболонці

4
додано
Швидше та безпечніше використовувати && exec mv - таким чином ви не намагаєтеся виконати перейменування, якщо cd не вдасться, і exec споживає дочірню оболонку, таким чином уникаючи покарання продуктивності.
додано Автор Charles Duffy, джерело
Я стверджую, що якщо ви збираєтеся пам'ятати лише один спосіб, пам'ятаючи ефективний спосіб допомагає переконатися, що ви не підете неефективним шляхом у тих випадках, коли це має значення.
додано Автор Charles Duffy, джерело
Погодьтеся з && для одноразового випадку, як я вже сказав, я б не хвилювався щодо вартості суб-оболонки (нехай це буде просто: можна легко запам'ятати, як це зробити більш важливі ІМО)
додано Автор cb303, джерело

Я б просто зробив

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory
2
додано

Якщо ви хочете увійти до підкаталогу, щоб скоротити команду mv , але хочете потім повернутися до поточного каталогу, є два способи зробити це. Один з них полягає в тому, щоб помістити cd і mv у підкрову (як вже було запропоновано).

Інший - використовувати pushd і popd для зміни каталогів:

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

Команда pushd подібна до cd , за винятком того, що вона спочатку натискає назву поточного каталогу на стек. popd видаляє найменування з стека і змінює його.

2
додано
pushd і popd - це розширення, призначені для інтерактивного використання. POSIX явно перераховує їх як "результати не визначені", а оболонку, створену для запуску сценаріїв (тобто на мінімальному вбудованому файлі) навколишнього середовища) не потрібно їх підтримувати.
додано Автор Charles Duffy, джерело

Рішення, яке включає: mv, щось {.txt, .txt.old} , використовує "башизм". Якщо ви бажаєте отримати більш портативний спосіб, використовуйте звичайні маніпуляції зі змінними:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"
0
додано
@CharlesDuffy ой ... Ти мене засмучуєш :(
додано Автор Olivier Dulac, джерело