我正在做OS考试练习。它需要获取当前目录中倒数第二个子目录的第三个最近文件。然后,我必须以相反的顺序打印其行。我不能使用tac命令。文字建议使用(awk和sed除外):头,尾巴,厕所。
我成功获取了所请求文件的文件名(但我认为太复杂了)。现在,我必须反向打印它。我想我可以使用这个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'
我该如何做得更好?如果第三个目录或第二个文件不存在怎么办?
答案 0 :(得分:1)
请参阅https://mywiki.wooledge.org/ParsingLs和awk '{system("test -d \"" $0 "\" && echo \"" $0 "\"")}'
正在调用shell来调用awk来调用系统来调用shell来调用测试,这显然比刚开始时仅进行shell调用测试要差。要做到这一点。此外,任何将整个文件读入内存的解决方案(如任何sed或天真的awk解决方案都将采用这种解决方案)将无法处理大型文件,因为它们将超过可用内存。
不幸的是,这是稳健地做您想做的事情:
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
将必须一次将整个文件读入内存,因此对于非常大的文件将失败,而sort则被设计为通过在必要时对tmp文件使用分页来处理大文件,并且一次仅将文件的一部分保留在内存中,因此这是有限的仅取决于设备上有多少可用磁盘空间。
以上要求GNU工具提供/处理NUL行尾-如果没有,请在\0
命令中将\n
更改为find
,删除{{ 1}},然后从awk命令中删除z
,请注意,只有在目录或文件名不包含换行符的情况下,结果才有效。