Работа UNIX, домашняя работа, не работает как хотелось конструкция ls -il | grep -i 'di'

Работа UNIX, домашняя работа, не работает как хотелось конструкция ls -il | grep -i 'di'

07.02.2020 12:18:41 Просмотров 25 Источник

Итак, есть задание

Вывести три первых элемента рекурсивного списка имен и атрибутов файлов в директории lab0, содержащих строчку "di", список отсортировать по убыванию даты изменения записи о файле, ошибки доступа перенаправить в файл в директории /tmp.

Не понимаю, как я могу связать команды ls и grep. Знаю что если написать find . -name 'g*' -type f -ls выйдет информация о файлах, с именами начинающимися на g, но с grep -ls связать не могу. Помогите пожалуйста.

У вопроса есть решение - Посмотреть?

Ответы - Работа UNIX, домашняя работа, не работает как хотелось конструкция ls -il | grep -i 'di' / Работа UNIX, домашняя работа, не работает как хотелось конструкция ls -il | grep -i 'di'

Total Pusher

07.02.2020 10:50:02

Если все правильно понял, то команда такая:

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-

оставшийся "хвост" такой трубы читается так:

  • обратная сортировка
  • выбрать первые три строки
  • вывести части, разбитые по пробелу, начиная со второй (удалить по пробелу дату модификации)
Закрыть X