Видалення файлів з пробілами в їх назвах


10

Я намагаюся видалити всі файли з пробілом у їх іменах. Я використовую наступну команду. Але це дає мені помилку

Команда: ls | egrep '. ' | xargs rm

Тут, якщо я використовую лише ls | egrep '. 'команду, це дає мені все ім'я файлу з пробілами у назви файлів. Але коли я намагаюся передати висновок в rm, всі пробіли (провідні або трейлінг) видаляються. Тому моя команда не виконує належним чином.

Будь-які вказівки щодо того, як видалити файл, маючи принаймні один пробіл у своєму імені?

Відповіді:


29

Ви можете використовувати стандартні глобулі в rmкоманді:

rm -- *\ *

Це видалить будь-який файл, ім'я якого містить пробіл; простір уникнути, тому оболонка не інтерпретує його як роздільник. Додавання --дозволить уникнути проблем із назви файлів, починаючи з тире (вони не будуть інтерпретуватися як аргументи rm).

Якщо ви хочете підтвердити кожен файл перед його видаленням, додайте -iпараметр:

rm -i -- *\ *

4
Ви ВІДКЛЮЧНО захочете провести це через echoперше, щоб уберегтися від помилок. Додайте echoспереду, і він виведе всі файли, які збирається видалити.
Riking

1
Ануй, причина, чому це має найбільше переваг, полягає в тому, що хоч findце потужно, іноді не потрібно вбивати курку кулеметом. Адміністратори UNIX, як правило, не вдаються до find(наприклад) "видалення всіх файлів, що починаються з літери A" ... можна було б просто rm A*. Так само для видалення файлів, що містять пробіли, rm може виконати роботу. Іншими словами, не обманюйте, оскільки простір невидимий і спеціально обробляється оболонкою. Просто уникайте цього, як це зробив Стівен Кітт, і ви можете думати про нього як про будь-якого іншого персонажа.
Майк Ш

14

Я б уникнув розбору lsрезультатів

Чому ні :

find . -type f -name '* *' -delete

Немає проблем з rm:-).

Хоча це рекурсивно і видалить усі файли з простором у поточному каталозі та вкладеними каталогами, як згадується в коментарях.


4
(1) ви можете використовувати -name '* *'замість регулярного виразу; і (2) ви можете використовувати -print0 | xargs -0 rm -iдля вирішення проблеми @ StephenKitt.
Кевін

1
Не потрібно xargs. Просто використовуйте-exec rm -i '{}' +
R .. GitHub ЗАСТАНОВИТИ ДІЙ

1
@Mhmd У ньому більше підводних каменів, ніж 8-бітна ігрова консоль. mywiki.wooledge.org/ParsingLs
Daenyth

1
Якщо ви хочете уникати підкаталогів, використовуйте find . -maxdepth 1 -name '* *' -delete.
Міккель

1
@BenjaminW. виправлено?
solsTiCe

6

Подивіться на це ім'я припущення "дивний файл"

Рішення одне

rm strange\ file

рішення два

rm "strange file"

рішення три

ls -i "strange file"

тоді ви бачите inode

find . -inum "numberoofinode" -exec rm {} \;

У випадку дуже дивних імен файлів, як

!-filename or --filename

використання

rm ./'!-filename'

4

З man xargs

xargs зчитує елементи зі стандартного вводу, розмежовані пробілами (які можна захистити подвійними або одиничними лапками або зворотною косою рисою) або новими рядками та виконує команду (за замовчуванням / bin / echo) один чи кілька разів з будь-якими послідовними початковими аргументами за елементами, прочитаними зі стандартного введення. Порожні рядки на стандартному вході ігноруються.

Ми можемо (в основному) виправити вашу початкову команду, змінивши роздільник розміру xargs на новий рядок:

ls | egrep '. ' | xargs -d '\n' rm (не робіть цього ... читайте далі)

Але що робити, якщо ім'я файлу містить новий рядок?

touch "filename with blanks and newline"

Оскільки назви файлів Unix можуть містити пробіли та нові рядки , така поведінка за замовчуванням часто є проблематичною; імена файлів, що містять пробіли та / або нові рядки, неправильно обробляються xargs. У цих ситуаціях краще використовувати варіант -0 , який запобігає подібним проблемам.

ls насправді є інструментом прямого споживання людиною , замість цього нам потрібно використовувати findкоманду, яка може розділити назви файлів з нульовим символом ( -print0). Нам також потрібно сказати grep, щоб використовувати нульові символи, щоб розділити вхід ( -z) і вихід ( -Z). Нарешті, ми кажемо xargs також використовувати нульові символи ( -0)

find . -type f -print0 | egrep '. ' -z -Z | xargs -0 rm



-1

Щоб зробити це таким чином, вам знадобиться -Zопція grep і -0параметр xargs. Але я б не робив це так ( lsце не правильний інструмент для роботи, є багато проблем з тим, щоб комп'ютер прочитав його вихід).

Дивіться інші відповіді для кращого способу.


Також

ls | …еквівалентно ls -d *іecho * | …

Усі вони мають проблеми. Тому не використовуйте lsподібне, використовуйте рішення з іншої відповіді.


Також, ls *коли труби виводять імена файлів з новою лінією з обмеженням. echo(принаймні деякі echoреалізації) розширює зворотні риси послідовностей. grep -Zпризначений для написання імен файлів, обмежених NUL при використанні -l, тут це не допоможе. Якщо ви мали на увазі -z, це не допоможе, оскільки для більшості lsреалізацій не вистачає можливості виводити імена файлів, обмежених NUL. Можна було б зробити щось на кшталт printf '%s\0' * | grep -z ' ' | xargs -r0 rm -fхоч.
Стефан Хазелас

1
@Kusalananda Я думаю, що я це виправив.
ctrl-alt-delor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.