Чому ця команда xargs не працює?


14

Я хотів видалити всі розширення .sh. Це так:

ls *.sh | xargs -I {} mv {} `basename {} .sh`

Однак це не працює, він поводиться так, що basenameповертає незмінене ім'я файлу.

Чому так поводиться?

Наприклад, це працює:

ls *.sh | xargs -I {} echo `basename {}.jpg .jpg`;

Редагувати :

Рішення: Одинична цитата запобігає `basename ...`оцінці оболонкою перед запуском команди.

ls *.sh | xargs -I {}  sh -c 'mv {} `basename {} .sh`'

Відповіді:


12

Оскільки команда basename виконується до запуску конвеєра. Для виконання цієї роботи вам потрібні xargs для виконання базового імені, і ви можете це зробити sh -c, наприклад:

ls *.sh | xargs -L1 sh -c 'basename $1 .sh' dummy

Примітки:

  • Якщо ви не вкажете, xargsкуди потрібно вставити імена файлів, вони будуть додані в кінці командного рядка.
  • Ви повинні використовувати -L1перемикач або його еквівалент, тому xargsпередає лише один аргумент sh.
  • Використання результату lsможе мати небажані ефекти .

Редагувати

Видалено застарілі параметри, завдяки TechZilla


3
Ваша перша точка невірна, якщо ви не мали на увазі, що за замовчуванням відповідає -iопція, але ці "класичні" параметри були застарілими. Наприклад, використовувати лише один параметр / рядок, нова сторінка "POSIX" рекомендує -L1. Щоб зателефонувати за старою поведінкою -i, сторінка рекомендує цю -I'{}'опцію.
Дж. М. Бекер

Отже, фактично про символи "", а не "". Я думаю, що "перешкоджає оцінці оболонки` `. Дивіться мої зміни.
majkinetor

@TechZilla: дякую за виправлення. @majkinetor: так і ні, вам потрібно відкласти оцінку, але я не думаю, що ви можете використовувати зворотні посилання (`).
Тор

1
@majkinetor: ах, я бачу, що ти маєш на увазі зараз. Для того, щоб перейменувати файли таким чином , я вважав за краще б використовувати rename, наприклад: rename 's/\.sh//' *.sh. Спершу спробуйте з сухого запуску ( -n).
Тор

1
@majkinetor: renameпрацює чудово і досить просто, але пам’ятайте, що це дуже конкретний розподіл. Розподіли на основі RHEL та Debian надають різні renameкоманди, тому потрібно пам’ятати про це при створенні сценаріїв крос-дистрибутива.
Дж. М. Бекер

4

Я не впевнений у вашому питанні, ви насправді запитуєте, чому ваш перший рядок не працює? Або шукаєте правильний метод для перейменування всіх .sh файлів?

Припускаючи, що це найчистіший метод, я вважаю за краще готувати параметри команд раніше xargs. Для видалення розширення файлу .sh я часто вважаю такий підхід,

 find -maxdepth 1 -type f -iname '*.sh'  | sed 'p;s_.sh$__' | xargs -L2 mv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.