Как получить n-й последний файл в n-ом последнем измененном подкаталоге, используя каналы - PullRequest
0 голосов
/ 07 июня 2019

Я делаю упражнение для экзамена ОС.Требуется получить 3-й последний файл 2-го последнего измененного подкаталога внутри текущего каталога.Затем я должен напечатать его строки в обратном порядке.Я не могу использовать команду TAC.Текст предлагает использовать (кроме awk и sed): head, tails, wc.

Мне удалось получить имя файла запрашиваемого файла (но я думаю, что это слишком сложно).Теперь я должен напечатать его в обратном порядке.Я думаю, что я могу использовать это решение awk https://stackoverflow.com/a/744093/11614625.

Вот как я получаю имя файла:

ls -t | head | awk '{system("test -d \"" $0 "\" && echo \"" $0 "\"")}' | awk 'NR==2 {system("ls \"" $0 "\" | head")}' | awk 'NR==1'

Как мне лучше?А что, если 3-й каталог или 2-й файл не существует?

1 Ответ

1 голос
/ 08 июня 2019

См. https://mywiki.wooledge.org/ParsingLs и awk '{system("test -d \"" $0 "\" && echo \"" $0 "\"")}' вызывает shell для вызова awk для вызова system для вызова shell to call test, что явно хуже, чем просто тестирование оболочки в первую очередь, если вы собираетесьсделай это.Кроме того, любое решение, которое считывает весь файл в память (как любое sed или простое awk-решение), не сможет работать с большими файлами, так как они превысят доступную память.

К сожалению, это то, что вы хотите делатьrobustly:

dir="$(find . -mindepth 1 -maxdepth 1 -type d -printf '%T+\t%p\0' |
       sort -rz |
       awk -v RS='\0' 'NR==2{sub(/[^\t]+\t/,""); print; exit}')" &&
file="$(find "$dir" -mindepth 1 -maxdepth 1 -type f -printf '%T+\t%p\0' |
       sort -z |
       awk -v RS='\0' 'NR==3{sub(/[^\t]+\t/,""); print; exit}')" &&
cat -n "$file" | sort -rn | cut -f2-

Если какая-либо из команд в каком-либо из каналов не будет выполнена, то будет напечатано сообщение об ошибке из команды, которая не прошла, и никакая другая команда не будет выполнена, и общий статус выхода будет сбоем.один из этой неудачной команды.

Я использовал cat | sort | cut, а не awk или sed, чтобы напечатать файл в обратном порядке, потому что awk (если вы не напишите в нем запрос страницы) или sedприходится считывать весь файл в память за один раз, поэтому для очень больших файлов произойдет сбой, в то время как сортировка предназначена для обработки больших файлов, используя при необходимости подкачку файлов tmp и сохраняя только части файла в памяти за раз, поэтому она ограничена толькосколько свободного дискового пространства у вас на устройствеКонечные строки NUL - если у вас их нет, измените \0 на \n в команде find, удалите z из параметров сортировки, удалите -v RS='\0' из команды awk и учтите, чторезультат будет работать только в том случае, если имена каталогов или файлов не содержат символов новой строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...