Получите дополнение к результату команды ls

Предположим, у меня есть каталог с несколькими файлами, все из которых являются либо двоичными файлами (файлы без объявленных расширений), либо исходными файлами (расширение .c ). Я делаю это:

$ ls

и получить:

README.md hello-world.c hello-world get-name.c get-name

и я хочу перечислять только файлы с определенными расширениями (скажем, как .c и .md ), я делаю:

ls *.c *.md

и все в порядке!

Но что, если теперь я хочу удалить все файлы, не имеющие расширения .c или .md , как я могу это сделать?

Я знаю, как это сделать с файлами, расширения которых мне известны, например:

ls *.c *.md | xargs rm

Но как я могу сообщить командной строке об удалении файлов, которые НЕ соответствуют моим критериям?

2 Solutions collect form web for “Получите дополнение к результату команды ls”

Используйте find :

 find -maxdepth 1 ! -name "*.c" -print0 | xargs -0 ... 

Обратите внимание, что -maxdepth , -print0 , -r и -0 находятся в нескольких реализациях find (были введены GNU find / xargs ), но не указаны POSIX. Другой способ, как сказал Стефан в своем комментарии, использовать -exec действие find – не забудьте использовать форму -exec command {} + , так как она значительно уменьшает количество вызовов command (она должна разрешать синтаксис, где имена файлов размещаются в конце, хотя вам нужно обернуть command внутри вызова sh -c ).

Альтернативно grep вывод ls

 ls | grep -v "\.c$" | xargs ... 

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

 ... | grep -v "\.\(c\|md\)$" | ... 

с расширенными регулярными выражениями:

 ... | grep -Ev "\.(c|md)$" | ... 

с параметром fixed strings (не будет соответствовать только в конце имени файла!):

 ... | grep -vF ".c .md" | ... 

или путем цепочки больше grep s:

 ... | grep -v "\.c$" | grep -v "\.md$" | ... 

Тем не менее, find , вероятно, лучший вариант, поскольку с параметром -print0 он обрабатывает все возможные символы в именах файлов, которые могут потребоваться в противном случае (если ваши find и xargs могут работать с строками с завершающим NULL – например, с инструментами GNU) ,

В ksh вы можете использовать:

 rm -- !(*.c|*.md) 

Эти расширения расширения также доступны в bash после shopt -s extglob и в zsh после setopt kshglob .

Ниже приведен коренной эквивалент zsh:

 setopt extended_glob rm -- ^(*.c|*.md) 

! в extglob «нет». Для вашей первоначальной команды это необходимо:

 rm -- *.c *.md 

Анализ вывода ls является ненадежным и будет разбит на некоторые имена файлов. См. Вики wiki для разбора ls .

  • Использование xargs с git
  • Не удалось создать большой файл tar с трубкой и xargs
  • Как рекурсивно бок о бок diff каталоги с номерами строк в diff в unix?
  • Проблемы с find, xargs и egrep
  • Как поддерживать порядок сортировки с помощью xargs и gunzip
  • Команда, которая печатает содержимое файла, указанное имя файла на stdin
  • Эффективная генерация stdin в сценарии оболочки
  • xargs -r0 vs xargs -0
  • как суммировать вывод awk или другого выражения с помощью xargs
  • Как мне получить xargs, чтобы показать мне строки команд, которые он генерирует, не запуская их?
  • Есть ли команда Unix для цитирования строк ввода?
  • Linux и Unix - лучшая ОС в мире.