Удалить пробелы в названиях файлов

Обновлено: 04.07.2024

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

Любые указатели о том, как удалить файл, по крайней мере один пробел в их имени?

Вы можете использовать стандартное перетаскивание в rm команде:

Это удалит любой файл, имя которого содержит пробел; пространство освобождается, поэтому оболочка не интерпретирует его как разделитель. Добавление -- позволит избежать проблем с именами файлов, начинающимися с тире (они не будут интерпретироваться как аргументы rm ).

Если вы хотите подтвердить каждый файл перед его удалением, добавьте -i опцию:

Вам определенно захочется пройти через это echo сначала, чтобы избежать опечаток. Добавьте echo спереди, и он распечатает все файлы, которые собирается удалить. Анудж, причина, по которой это вызывает наибольшее количество голосов, заключается в том, что, хотя find это мощно, иногда вам не нужно убивать курицу из пулемета. Администраторы UNIX, как правило, не прибегают find (например) к «удалению всех файлов, начинающихся с буквы A» . просто так rm A* . Аналогично, чтобы удалить файлы, содержащие пробелы, rm может сделать эту работу. Другими словами, не обманывайте себя, потому что пространство невидимо и обрабатывается специально оболочкой. Просто избежите этого, как сделал Стивен Китт, и вы можете думать об этом как о любом другом персонаже.

Я бы не стал разбирать ls вывод

Почему бы и нет :

Нет проблем с rm :-).

Хотя это рекурсивно и удалит все файлы с пробелами в текущем каталоге и вложенных каталогах, как упомянуто в комментариях.

(1) вы можете использовать -name '* *' вместо регулярного выражения; и (2) вы можете использовать -print0 | xargs -0 rm -i для решения проблемы @ StephenKitt. Нет необходимости xargs . Просто используйте -exec rm -i '<>' + Если вы хотите избежать подкаталогов, используйте find . -maxdepth 1 -name '* *' -delete .

Посмотрите на это Предположим, имя "странный файл"

тогда вы видите инод

В случае очень странных имен файлов, таких как

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

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

Но что, если имя файла содержит новую строку?

touch "filename with blanks and newline"

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

ls это действительно инструмент для непосредственного потребления человеком , вместо этого нам нужно использовать find команду, которая может разделять имена файлов нулевым символом ( -print0 ). Мы также должны указать grep использовать нулевые символы для разделения input ( -z ) и output ( -Z ). Наконец, мы говорим Xargs также использовать нулевые символы ( -0 )

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

Я использую следующую команду с Thunar Custom Actions, чтобы убрать имена файлов:

Но эта команда заменяет только пробелы / дефисы и символы в нижнем регистре.

Я использовал следующую команду в терминале для удаления пробелов из тысяч имен файлов в папке, и она работала довольно быстро:

Опять же, он удаляет только пробелы, а не дефисы / тире и подчеркивания.

В идеале я не хочу пробелов, дефисов / тире и подчеркиваний в моих именах файлов. И было бы здорово, если бы эту команду можно было использовать с пользовательскими действиями Thunar для выбранных файлов.

Я отмечаю одну проблему, которая существует во многих предлагаемых решениях, - это неправильная проверка наличия «нового» имени перед запуском файла. Невыполнение этого требования может стать источником многих проблем. Можно ли изменить команду John1024, чтобы проверить это? Спасибо, ястреб. Кстати, для тех, кто заинтересован в использовании этого в качестве настраиваемого действия Thunar, команда для Thunar: для файла в% N; сделать mv "$ file" echo $file | sed -e 's/[ _-]//g' ; сделано

Версия rename , поставляемая с perl пакетом, поддерживает регулярные выражения:

С другой стороны,

-i Флаг будет сделать rename использовать интерактивный режим, побуждая , если цель уже существует, вместо того , чтобы молча перезапись.

Переименование Perl иногда называют prename .

Переименование Perl против переименования util-linux

В Debian-подобных системах переименование perl выглядит по умолчанию, и вышеприведенные команды должны просто работать.

В некоторых дистрибутивах rename утилита из util-linux используется по умолчанию. Эта утилита полностью несовместима с Perl rename .

Все: во- первых, проверьте, rename доступен ли Perl под этим именем prename .

Debian: переименование Perl должно быть по умолчанию. Это также доступно как prename . Однако rename исполняемый файл находится под контролем /etc/alternatives и, таким образом, мог быть изменен на что-то другое.

archlinux: Запустите pacman -S perl-rename и команда доступна как perl-rename . Для более удобного имени создайте псевдоним. (Наконечник шляпы: ChiseledAbs)

Mac OSX Согласно этому ответу , rename может быть установлен на OSX с помощью homebrew через:

Прямая загрузка: rename также доступна от Perl Monks:

Я думаю, это зависит от того, о чем rename ты говоришь. Тот из util-linux -2.24.2-1.fc20.x86_64 не поддерживает регулярные выражения. @CristianCiupitu Я только что проверил страницу руководства для версии переименования, которую вы нашли. Исходя из аргументов, версия, rename которую использовал OP, выглядит как perl версия, а не util-linux версия. Для справки, это rename справочная страница для версии util-linux . В любом случае, кроме этой записки, важно то, что ОП получил свой ответ (и вы от меня откликнулись :-D). @CristianCiupitu Спасибо, что нашли это. Обратно к вам с +1. @ John1024 archlinux, но я узнал как, просто иди pacman -S perl-rename тогда, я думаю, вы можете псевдоним.

Я бы заменил все эти tr команды sed командой подстановки, например:

Не считая mv , вам вообще не нужен внешний процесс для этого - вы можете просто как-то их испортить .

Тем не менее, это означает, что mv вызов для файла, и, вероятно rename , лучше. Хотя это должно срабатывать , только POSIX mv в $PATH и POSIX оболочки.

Итак, я придумал какое-то сумасшедшее демо для этого. Тестовый набор генерируется как:

Во-первых, я буду первым, кто признает, что приведенная выше команда дает результаты, которые легче получить другими способами. Но другие средства, вероятно, также не продемонстрируют, что можно сделать с $IFS небольшим (больным?) Воображением.

Итак, первый бит довольно прост:

tee передает 5 копий входных данных - наследственный документ называется CGEN

dd блокирует его ввод с помощью новых строк по 90 байт на блок и передает это .

sed объединяет 2 из этих блоков в два \n символа ewline, заключает в ' кавычки результаты и добавляет строку touch -- для каждого цикла строки перед тем, как передать .

sh который затем выполняет весь ввод как команды оболочки

дно printf печатает 252 0с

следующий из последнего получает 252 '' аргумента с нулевой строкой, и для каждого из них выводится содержимое, за $n которым следует строка " $i "

eval интерпретирует аргументы следующего до того, printf как он напечатает результаты этой интерпретации как восьмеричные числа с добавлением двух обратных косых черт

последний printf выводит значения байтов для этих восьмеричных чисел 2 за раз, за ​​которым следует строка -_ ---___ для каждой пары

$n инициализируется уравнением, которое будет увеличиваться $i на единицу для каждой оценки, за исключением того, что оно пропускает значения 10, 39 или 47 - (которые являются \n ewline, ' одинарными кавычками и / косой чертой в десятичном формате ASCII соответственно)

Конечным результатом является каталог, содержащий множество действительно уродливых имен файлов, содержащих каждый байт в моей кодировке от 1 до 255, за исключением одинарных кавычек (пропущен только для того, чтобы избежать еще одного sed s/// оператора) и / косой черты. Эти имена файлов выглядят так:

Теперь я получу некоторые данные об этих файлах:

ВЫВОД

ОК. Теперь, наконец, к действию:

ВЫВОД

Успех! Вы можете увидеть сами:

@ John1024 - что действительно весело: set -- 'some arbitrary' args; eval printf '"%s\n"' "$(IFS=0; printf ' "$@" %s' $(printf %025d))" new="$(IFS=" -_"; printf %s $1)" разветвляется подоболочка (кроме ksh93) и имеет проблемы с переводом строк. Другой вариант - использовать IFS=' -_'; set -- $1; IFS=; new="$*" (и изменить цикл while на цикл for) [ -e x ] вернет false, если x это символическая ссылка на несуществующий или недоступный файл.

если у вас есть Perl, вы обычно переименовываете. ты можешь сделать:

и покажите, как написан этот скрипт:

Этот скрипт не поддерживает флаг -i (это версия в моей системе), но, возможно, ваш поддерживает. Как насчет аргументов. Во-первых, это регулярные выражения в формате PCRE, он работает как фильтр, изменяет имя ввода на имя вывода. Список названий вводимых вами звездочек '*'. например, вы делаете:

в действительности '*' может быть расширен до:

Когда у вас действительно большое количество файлов, вы попали в ловушку. Оболочка будет расширять вашу линию дольше, чем система принимает. тогда вы можете сделать обходной путь, используя find или xargs. использование 'find' является проблемой, потому что переименование будет вызываться много раз, равное количеству файлов в каталоге. лучше использовать xargs с опцией -r. один переименовать вызов изменить много файлов. например:

Последняя проблема, что это значит:

это регулярное выражение для изменения имен. после первого '/' пробел. это обнаруживается и заменяется строкой после второго '/'. Но есть пустая строка, оканчивающаяся на третью '/', затем пробел заменяется ничем. Опция «g» делает это выражение повторяющимся. выражение будет идти по всему имени от начала до конца и обнаруживает все пробелы.

Но что, если у вас есть символ табуляции или другой «белый» символ? есть замена для этого '\ s'. какие еще ненужные персонажи? просто добавьте это к выражению. Все закрываются скобками, например:

это все. ты видишь сходство? Я думаю, вы должны прочитать man perlrequick и man perlretut, это объяснит вам (я надеюсь), как работает регулярное выражение. Вы можете использовать команду переименования в своем собственном скрипте, если вам это нужно.

Кто-то из моих знакомых выразил сегодня раздражение в отношении тех из нас, кто не использует пробелы в наших именах файлов, например, NamingThingsLikeThis.txt несмотря на то, что большинство современных операционных систем поддерживают пробелы в именах файлов.

Существуют ли технические причины , по которым все еще можно увидеть имена файлов без (соответствующих) пробелов? Если да, то каковы эти технические причины того, что пробелы в именах файлов избегаются или не поощряются, и при каких обстоятельствах они актуальны?

Самая очевидная причина, по которой я мог придумать, и почему я обычно избегаю этого, - это дополнительные кавычки, необходимые в командной строке при работе с такими файлами. Есть ли другие важные технические причины?

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

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

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

Это, и старые привычки тяжело умирают.

Они - также правильная королевская боль, с которой нужно иметь дело, тогда вы должны составить пути и изменить их. Перед повторным экранированием / повторным цитированием убедитесь, что компоненты не заключены в кавычки и не экранированы для модификации, особенно если части отправляются в другие биты кода для манипуляции. Если вы думаете, что пробелы плохие, попробуйте работать с файлами с символами новой строки ( '\n' ) в их именах. (Unix-подобные системы на самом деле позволяют это; Windows вообще или, по крайней мере, затрудняет это.)

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

Одной из самых раздражающих вещей в отношении пробелов, которые необходимо кодировать в URL-адресах, является склонность определенного программного обеспечения в конечном итоге сохранять закодированные пробелы . @ChrisCalo Вы можете заметить, что этот ответ был дан в 2009 году, а не в 2018. Но, да, это все еще происходит в 2018 году. Возможно, реже, теперь, когда большинство начинающих разработчиков используют фреймворки для создания сайтов, а не делают все с нуля, но все же вопрос.

Многие причины исторические. Это не значит, что они не имеют смысла сегодня.

Проблемы в мобильности

При именовании файла вам также может понадобиться учитывать, как другие (файловые) системы будут обращаться с этим именем файла. Символ в имени файла может подойти для вашей системы, но это может быть проблемой для другой системы.

Таким образом, до тех пор, пока существует малейшая вероятность того, что вы захотите легко получить доступ к файлу из старой системы, вы выбираете только безопасный символ. Это может включать загрузку старой системы восстановления, которую вы держали, или страх, что последние версии Windows по-прежнему основаны на MS-DOS.

длина

Файловая система может ограничивать длину файла. Это было еще более серьезно в те дни, когда MS-DOS ограничивался 8,3 именами файлов . Таким образом, оставляя пробелы, вы можете поместить в имя более значимые символы.

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

Зарезервированные персонажи

MS-DOS также определил символ пробела как зарезервированный символ. Это связано с тем, что символ пробела использовался для заполнения в FAT . Кроме того, MS-DOS не обеспечивала экранирующую систему в оболочке.

Интерпретация командной строки

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

Рассмотрим разницу между

В статье WikiPedia, указанной выше, даже указывается на двусмысленность, возникшую из-за отсутствия правильного экранирования команды:

Неоднозначность может быть предотвращена либо путем запрета встроенных пробелов в именах файлов и каталогов, в первую очередь (например, путем замены их символами подчеркивания '_'), либо, если поддерживается интерпретатором командной строки и программами, принимающими эти параметры как аргументы, заключая в себе имя со встроенными пробелами между символами кавычек или используя escape-символ перед пробелом, обычно обратную косую черту ('\'). Например

является неоднозначным (является ли «имя программы» частью имени программы или двумя параметрами?); тем не мение

и Long \ path / Long \ program \ name Параметр \ один Параметр \ два .

не являются двусмысленными.

Унифицированные указатели ресурсов (URL)

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

Персонажи могут быть небезопасными по ряду причин. Символ пробела небезопасен, так как значительные пробелы могут исчезнуть, а незначительные пробелы могут быть введены, когда URL-адреса транскрибируются, набираются или подвергаются обработке программ обработки текста.

Таким образом, пробел должен быть заменен %20 вместо. Это делает имя файла частью URL менее читабельным и, таким образом, заставляет людей избегать его в первую очередь.

Читайте также: