Работа UNIX, домашняя работа, не работает как хотелось конструкция ls -il | grep -i 'di'
Итак, есть задание
Вывести три первых элемента рекурсивного списка имен и атрибутов файлов в директории lab0, содержащих строчку "di", список отсортировать по убыванию даты изменения записи о файле, ошибки доступа перенаправить в файл в директории /tmp.
Не понимаю, как я могу связать команды ls и grep. Знаю что если написать find . -name 'g*' -type f -ls выйдет информация о файлах, с именами начинающимися на g, но с grep
-ls связать не могу. Помогите пожалуйста.
Ответы (1 шт):
Если все правильно понял, то команда такая:
grep -rl --null di lab0 2>/tmp/error.txt | xargs -0 stat -c "%Y %n %A" | sort -r | head -n3 | cut -d" " -f2-
Чтобы такое соорудить, нужно знать три вещи:
- что есть перенаправления потока данных из одной команды в другую или в файл (
|,>), а без этого такую сложную задачу не решить - знать подходящие команды,
findтут не нужен, аgrepможет сам искать рекурсивно - есть встроенная справка:
man grep,man stat, ..., хотя я часть аргументов таки нашел через Гугл
Пройдемся по порядку, чтобы была понятна суть
grep -rl di lab0
-r - рекурсивно, -l - вернуть только список. у меня получился такой список:
lab0/lab/1/2/3/6.txt
lab0/lab/1/2/3/5.txt
grep: lab0/lab/1/2/3/100.txt: Отказано в доступе
lab0/lab/1/2/3/1.txt
lab0/lab/1/2/3/4.txt
lab0/lab/1/2/3/2.txt
lab0/lab/1/2/3/a b c.txt
2. получение даты модификации
для последующей сортировки нужно получить информацию о всех файлах в таком формате: дата-модификации имя-файла
ls не может вывести в таком формате, но есть команда stat
man stat:
-c --format=FORMAT
use the specified FORMAT instead of the default; output a newline after each use of FORMAT
%Y time of last data modification, seconds since Epoch
%n file name
%A access rights in human readable form
Но напрямую stat не читает поток, grep ... | stat ... сделать не получится. Поэтому используем xargs:
grep -rl --null di lab0 2>/tmp/error.txt | xargs -0 stat -c "%Y %n %A"
тут:
2>/tmp/error.txt- перенаправление ошибок в файл--null- выводить список файлов не через пробел, а через null-терминированные строки, иначе будет ошибка, если в имени файла есть пробел-0- уже дляxargxозначает читать файлы, перечисленные построчно, а не через пробелxargsуже вызываетstat
получилось так:
1581101904 lab0/lab/1/2/3/6.txt -rw-rw-r--
1581101904 lab0/lab/1/2/3/5.txt -rw-rw-r--
1581102146 lab0/lab/1/2/3/1.txt -rw-rw-r--
1581101904 lab0/lab/1/2/3/4.txt -rw-rw-r--
1581101904 lab0/lab/1/2/3/2.txt -rw-rw-r--
1581102859 lab0/lab/1/2/3/a b c.txt -rw-rw-r--
3. сортировка, лимит и удаление лишнего
| sort -r | head -n3 | cut -d" " -f2-
оставшийся "хвост" такой трубы читается так:
- обратная сортировка
- выбрать первые три строки
- вывести части, разбитые по пробелу, начиная со второй (удалить по пробелу дату модификации)