Как удалить файлы, отфильтрованные awk

У меня есть следующие файлы в каталоге:

-rw-r--r-- 1 smsc sys 46 Apr 22 12:09 bills.50.1.3G.MO.X.20120422120453.Z -rw-r--r-- 1 smsc sys 28 Apr 22 12:15 bills.50.1.3G.MO.X.20120422120953.Z -rw-r--r-- 1 smsc sys 46 Apr 22 12:20 bills.50.1.3G.MO.X.20120422121453.Z -rw-r--r-- 1 smsc sys 46 Apr 22 12:25 bills.50.1.3G.MO.X.20120422121953.Z 

Где пятый столбец – это размер файла. Я хочу удалить все файлы размером 46. Чтобы отфильтровать эти файлы, я использовал следующую команду:

 ls -ltr | awk '$5 ~ /46/ {print $0}' 

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

 ls -ltr | awk '$5 ~ /46/ {print $0}' | xargs rm 

Однако это дает мне следующую ошибку:

 rm: invalid option -- w 

Кажется, что мне нужно использовать find over ls поэтому я получу результат в следующем формате:

 ./bills.50.1.3G.MO.X.20120421050453.Z ./bills.50.1.3G.MO.X.20120421154953.Z ./bills.50.1.3G.MO.X.20120419133452.Z 

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

  • Интерактивное удаление файлов, перечисленных с помощью путей в текстовом файле
  • вывод технологического процесса на команду split by line и whitespace
  • Найти файлы рекурсивно, которые старше одного года и не принадлежат конкретному пользователю
  • Когда вы должны использовать подоболочки vs `xargs`?
  • Есть ли способ сделать этот однострочный лайнер быстрее?
  • создать хеш md5 из рекурсивного списка файлов, когда некоторые пути имеют пробелы
  • cmd2 `cmd1` vs cmd1 | xargs cmd2
  • Как я могу рекурсивно заменить строку в именах файлов и каталогов?
  • 3 Solutions collect form web for “Как удалить файлы, отфильтрованные awk”

    У вас есть две ошибки:

    1. Вы сравниваете размер, который содержит 46 ; вы хотите, чтобы он был равен 46.

    2. Вы печатаете всю строку, если хотите только имя файла.

    И еще одна проблема: какая точка -ltr сортирует вывод ls если вы не используете порядок сортировки?

    Вы хотите сделать что-то вроде

     ls -l | awk '$5 == "46" {print $9}' | xargs rm 

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

     find . -maxdepth 1 -size 46c -delete # requires GNU find 

    (Выполнение этой переносимости более раздражает, так как у POSIX find нет -maxdepth или -maxdepth который работает в единицах, отличных от блоков. Лучше написать скрипт в Perl / Python / Ruby / etc, который может использовать правильное сканирование каталога это не вызовет проблем со специальными символами в именах файлов.)

    В zsh, чтобы удалить все файлы размером 26 в текущем каталоге (первая строка) или в текущем каталоге и его подкаталогах (вторая строка), используйте классификатор L glob :

     rm *(L26) rm **/*(L26) 

    С GNU или FreeBSD / NetBSD / OSX найдите:

     find . -name . -o -type d -prune -o -type f -size 26c -exec rm {} + find . -type f -size 26c -exec rm {} + 

    Портабельно:

     find . -name . -o -type d -prune -o -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \; find . -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \; 

    find лучший вариант здесь. вы можете использовать stat чтобы найти размер файла, не используя ls

     for file in *; do (( $(stat -c %s "$file") == 46 )) && rm "$file" done 
    Linux и Unix - лучшая ОС в мире.