#bash
#bash
Вопрос:
У меня есть домашнее задание, которое требует, чтобы я сделал это:
Напишите скрипт, который с помощью awk сканирует все файлы, которые были изменены сегодня и имеют размер <= 1 Мбайт (меньше или равно). Скрипт должен выполнить рекурсивный поиск по всем файлам из указанного вами местоположения (аргументы скрипта) и вывести их в стандартный вывод (терминал).
Я уже делал это:
find . -type f -size 1M -exec stat -c '%X %n' {} ;
| sort -nr
| awk 'NR==1,NR==3 {print $2}'
Как мне удается принимать пути в качестве аргумента для скрипта и автоматически выводить все результаты в терминале? Возможно, я также неправильно ввел строку find?
Комментарии:
1. Это очень глупое задание просить вас использовать awk для чего
find
-то, что само по себе может делать только со встроенной функциональностью.2. В любом случае, вы показали назначение и вашу попытку его выполнения, но вы не задали вопрос о конкретной проблеме с вашим кодом , с которой вы столкнулись при выполнении этого. Это не то, что вы подразумеваете под «использовать пути в качестве аргумента» — какая часть назначения говорит вам это сделать? И
NR
было бы подходящим способом решить, из каких строк печатать второе поле.3. Моя проблема в том, как добавить функциональность аргумента, позволяет пользователю указывать путь к папке для выполнения этой функции, и правильно ли написан мой «find» на основе назначения?
4.Почему вы используете
sudo
для доступа к собственному рабочему столу? В любом случае, наиболее очевидным объяснением является то, что сообщение об ошибке правильное и/Home/Desktop
не существует:/Home
это не обычный путь, отсутствующий ни в обычном UNIX, ни в macOS;"$HOME/Desktop"
гораздо более типично.5. Я думаю, что вам не хватает намерения назначения. Если вы хотите рекурсивно найти все файлы, которые соответствуют некоторым критериям, вы можете просто использовать find ( awk излишен). Учитывая это, я бы предположил, что инструктор хочет, чтобы вы написали всю функцию в awk.
Ответ №1:
Вы можете сделать все это в find
(по умолчанию в Linux). Просто используйте аргументы скрипта в качестве целевых каталогов:
#!/bin/sh
find "$@" -type f -size -2M -mtime -1
$@
Расширяется до списка аргументов. -size -2M
Означает «меньше 2 м», но обратите внимание, что find
это округлит до следующей единицы. Таким образом, файл размером 1,1 Млн считается 2 млн, вот почему вы хотите, -2M
а не -1
. Наконец, -mtime -1
находит только файлы, измененные в течение последних 24 часов.
Теперь, если ваш учитель хочет, чтобы вы каким-то образом подключились awk
к этому, вы можете сделать что-то вроде этого:
#!/bin/sh
find "$@" -type f -mmin -1440 -exec stat -c '%s %n' {} |
awk '$1<=1048576'
Затем вы запускаете свой скрипт с целевыми каталогами в качестве аргументов:
foo.sh /path/to/dir1 /path/to/dir2 ... /path/to/dirN
Если ваш учитель настаивает на выполнении всего этого в awk
, вы могли бы сделать:
#!/bin/sh
now=$(date %s)
aDayAgo=$((now - 86400))
find "$@" -type f -mmin -1440 -exec stat -c '%s %X %n' {} |
awk -vaDayAgo="$aDayAgo" '$1<=1048576 amp;amp; $2>=aDayAgo'
Конечно, это означает, что ваш скрипт будет отключен на столько секунд, сколько потребуется для его запуска, поскольку время не остановится, пока вы его запускаете. Но это вряд ли будет серьезной проблемой.
Комментарии:
1. Одно предостережение: это возлагает на вызывающую сторону нагрузку по обеспечению того, чтобы каталог с именем (например)
-foo
передавался как./-foo
, чтобыfind
не принять его за основной.