it-swarm-ru.tech

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

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

34
SpecialBomb

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

  1. Вы можете прекратить указывать это дробовик на вашу ногу. По сути, любой вид синтаксического анализа ls будет более сложным и подверженным ошибкам чем установленные методы, такие как find [...] -exec или globs .
  2. Если кто-то не установил для вас дистрибутив тролля, в вашей оболочке есть Tab завершение. Просто введите rm google и ​​нажмите Tab, Если он не завершится сразу, нажмите Tab снова, чтобы увидеть список подходящих файлов. Введите больше символов имени файла, чтобы сузить его, пока оно не завершится, затем выполните команду.
  3. Трубы ! = параметры . Стандартный ввод - это поток двоичных данных , который может быть передан команде асинхронно. Параметры - это разделенные пробелами строки, которые передаются команде один раз и только один раз при ее запуске. Они очень редко взаимозаменяемы.
57
l0b0

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

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

ls | grep chrome | xargs rm

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

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

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

35
John

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

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

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

34
chander

Никогда не анализировать вывод 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)

Более быстрый и более опасный путь  [], должен использовать !!

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

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

12
Hastur
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' или какой-то другой шаблон, который вам подходит.

5
mikeserv

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

2
David King