Как передать ls в grep и удалить файлы, отфильтрованные по grep?

33

Я хотел удалить какой-то пакет в моем домашнем файле, но имя файла было слишком длинным ( google-chrome-stable_current_i386.deb). Итак, я решил использовать команду ls|grep chrome|rmдля передачи файлов в grep, чтобы отфильтровать файл chrome, а затем удалить его. Это не сработало, поэтому я хотел бы посмотреть, как я могу это сделать.

SpecialBomb
источник
22
rm -i *chrome*.deb
Ламберт
28
Вообще говоря, мне не нравится, когда люди публикуют ответы «не делай этого», но это один из лучших примеров проблемы XY, которую я когда-либо видел. Ваш реальный вопрос заключается в том, «как быстро удалить файл с длинным именем файла, не печатая всего текста», и есть много хороших способов, которые не включают в себя вывод результатов изls
Michael Mrozek
5
Просто используйте find- find . -name "*chrome*" -delete.
Борис Паук
3
Мои два цента как пользователя StackExchange: в будущем задайте свой вопрос более общим способом, предоставив подробную информацию о том, что вы пробовали. "Как мне удалить файлы в папке с определенной строкой в ​​имени файла?" возможно, был бы лучший способ выразить это. Тогда вы могли бы просто добавить, как в сторону, что вы пытались трубопровода lsчерез grepк , rmно не мог заставить его работать. Таким образом, вы получите один или два хороших ответа о «правильном» или «простом» способе выполнения вашей задачи, вместо того, чтобы заставлять кого-то дать вам хороший ответ о неэффективном решении.
Адриан

Ответы:

56

Это почти заставило меня вздрогнуть.

  1. Возможно, вы захотите перестать направлять этот дробовик на вашу ногу. В принципе любого вида разбора lsсобирается быть более сложным и подверженные ошибкам , чем установленные методы , как find [...] -execи комки .
  2. Если кто-то не установил для вас дистрибутив тролля, ваша оболочка Tabзавершена. Просто введите rm googleи нажмите Tab. Если он не завершится немедленно, нажмите еще Tabраз, чтобы увидеть список подходящих файлов. Введите больше символов имени файла, чтобы сузить его, пока оно не завершится, затем выполните команду.
  3. Трубы ! = Параметры . Стандартный ввод - это двоичный поток данных, который может передаваться команде асинхронно. Параметры - это разделенные пробелами строки, которые передаются команде один раз и только один раз при ее запуске. Они очень редко взаимозаменяемы.
l0b0
источник
1
Извините, если это показалось вопросом n00b. Я знал, что это нормально для использования в целом, поскольку указанный пакет был единственным пакетом с указанным в нем «хромом». Следовательно, использование grep отфильтровывает только один файл. Я довольно новичок в Linux, и я уже сделал много сценариев bash, но я еще не знаю всего: P. Суровый, чувак.
SpecialBomb
5
Не хотел быть резким, но оболочка - жесткая и неумолимая среда, скрытая за своего рода дружественной к пользователю поверхностью. Делать вещи безопасно достаточно сложно, не говоря уже о том, чтобы безопасно или даже правильно .
10
2
@SpecialBomb Это единственный правильный ответ. Объяснение того, как правильно прицелиться в ружье, чтобы аккуратно отрезать ногу, как это делают другие ответы, конечно же, не тот путь. Будьте особенно осторожны с слепым исполнением rm- это, вероятно, самый распространенный способ поджарить ваш дистрибутив.
Борис Паук
@BoristheSpider Хех, я определенно уже готовил Ubuntu дважды, устанавливая драйверы видеокарт AMD. Я уже задавал вопрос об этом, хотя. AMD была ужасна, поэтому я спросил, есть ли какие-нибудь общие исправления или лучшие способы игры с Linux на карте AMD.
SpecialBomb
34

Вы также можете использовать команду find с подстановочным знаком:

find . -maxdepth 1 -name '*chrome*' -delete

Обратите внимание, что аргумент "-maxdepth" гарантирует, что поиск работает только в текущем каталоге и не переходит в подкаталоги.

Chander
источник
1
Предложения по улучшению: (а) использовать -inameдля имен файлов без учета регистра (б) путь к xargsиспользованию -print0флага для findи -0флага для xargs. Использование xargsпозволяет делать такие вещи, как «интерактивное» (подтвердить удаление foo?) Удаление .
Кристофер Шульц
3
Нет необходимости транслировать в xargs, если вы используете опцию -exec:find . -name '*chrome*' -exec rm -i {} +
Джонни
4
Разве это также не удалит рекурсивно в подкаталоги? Возможно, вам нужно будет указать maxdepth1.
Tyzoid
32

Вы правильно поняли, просто пропустили некоторые детали. Поскольку вы имеете дело со списком, поступающим в STDIN и rmожидающим параметры, вам необходимо использовать xargs.

Таким образом:

ls | grep chrome | xargs rm

Должен дать вам то, что вы хотите.

Обратите внимание, что если вы хотите удалить все, кроме chromeфайла, вы можете просто добавить -vк grepзаявлению.

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

Джон
источник
С -v, не будет ли это удалить все, кроме файлов, которые соответствуют chrome? Я не думаю, что это то, что хочет ОП ...
akivajgordon
Смотря снова, ты прав. ОП хочет «отфильтровать файл chrome», но затем хочет удалить его.
Джон
Это кажется излишне сложным по сравнению с простым «rm -i chrome »
чандер
5
Принятый ответ работает, но посмотрите ответ ниже, который объясняет, почему это плохая идея. (Размещать этот комментарий здесь только ради тех, кто останавливается, как только видит «принятую» галочку.)
Джим Дэвис,
1
Таким образом, принятый ответ «работает», только если в lsвыводе нет «странных» имен файлов . Имена файлов с пробелами разрушат это. Это также опасно, если кто-то может создать имя файла со специальным соусом в каталоге, где вы его запускаете. Как уже указали несколько человек, не анализируйте вывод ls !
Стивен П
11

Никогда не анализируйте выходные данные ls.
Я предлагаю избегать синтаксического анализа выходных данных ls [ 1 ] , даже больше, если это связано с delкомандой. Это по многим причинам в основном связано с неожиданными и не обычными символами, разрешенными в имени файла.

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

Лучше использовать findрасширение вкладки (начните писать имя и нажмите Tab), расширение имени файла [ 2 ] как *MyKey*...


Быстрое решение
Поскольку вы хотите выбрать все пакеты (которые заканчиваются .deb) с помощью "google" внутри, вы можете создать свой запрос с помощью подстановочного знака * *google*.debи сделать простой

rm -i *google*.deb 

это выберет каждое имя файла с "google" в середине, которое будет отображаться .debв текущем каталоге. Опция -i(интерактивная) запросит подтверждение, что является хорошей привычкой при удалении файлов с расширением параметра.


Решение, близкое к философии вашей попытки.
Если ваша цель состоит в том, чтобы строить фрагмент командной строки за фрагментом, то есть вы сделали это lsпосле ls | grep google, и только после проверки выходных данных, вы можете выполнить их в подоболочке $(...)с помощью

rm -i $(ls | grep google)

Более быстрый и опасный способ [ 3 ] заключается в использовании!!

ls | grep google
rm -i $(!!)

это выполнит последнюю команду, законченную в вашей истории . Вы можете защитить себя от того факта, что у вас нет визуального контроля над строкой, которую вы собираетесь выполнить, если вы заранее включили параметры оболочки histverifyс помощью shopt -s histverify.

Hastur
источник
5
touch 0 1 2 3 4 5 6 7 8 9
find . -name \[0-9] -ok rm {} \;

< rm ... ./0 > ? y
< rm ... ./9 > ? y
< rm ... ./8 > ? y
< rm ... ./7 > ? y
< rm ... ./6 > ? y
< rm ... ./5 > ? y
< rm ... ./4 > ? y
< rm ... ./3 > ? y
< rm ... ./2 > ? y
< rm ... ./1 > ? y
^C

... используйте -name '*c*.deb'или какой-либо другой шаблон, который вам подходит.

mikeserv
источник
2

rmне принимает входные данные от stdin. Вам нужно будет сделать что-то вродеls google-chrome* | xargs rm

Дэвид Кинг
источник