我是 Linux 的新手,目前我遇到了一个问题。我想从文件夹中获取扩展名列表(.doc、.pdf)。我在谷歌上搜索了很多,最后我得到了下面给出的解决方案:
find . -type f | awk -F. '!a[$NF]++{print $NF}'
我明白找到。 -type f
,但无法理解 awk -F。 '!a[$NF]++{print $NF}'
是什么意思?
NF = 当前记录中的字段数
谁能解释一下?
提前致谢。
最佳答案
要回答您的问题,awk
行在做什么:
正如您已经指出的那样,行 find 。 -type f
返回位于当前目录中的文件列表。例如。
./foo.ext1
./bar.ext2
./spam.ext2
./ham.ext3
./spam.ham.eggs
此文件列表通过管道发送到命令 awk -F。 '!a[$NF]++{print $NF}'
。这个 awk 行包含很多信息。首先你需要知道 awk 是一个记录解析器,其中每条记录由许多字段组成。默认记录是 line
而默认字段分隔符是空格序列。那么你的 awk 行现在做什么:
-F.
::这将字段分隔符重新定义为点 (.
)。从这一点开始,示例中的所有行现在都有 2 个字段(例如第 1 行foo
和ext1
),而最后一行有 3 个字段(spam
、火腿
和鸡蛋
)。NF
::这是一个awk
变量,返回每条记录的字段数。很明显,扩展是用最后一个字段($NF
) 表示的
a[$NF]
::这是一个数组,其中索引是扩展名。默认数组值为零
,除非您为其赋值。a[$NF]++
::这会返回a[$NF]
的当前值,并在返回后将该值加 1。因此对于第 1 行,a["ext1"]++
返回0
并将a["ext1"]
设置为1
。而对于第 3 行,a["ext2"]++
返回1
并将a["ext2"]
设置为2
。这表示a[$NF]
跟踪$NF
出现的次数。!a[$NF]++
::这结合了上述逻辑,但检查a[$NF]++
的返回值是0
。如果是0
,返回true
,否则返回false
。对于示例的第2
行,此语句将返回true
,因为a["ext2"]++
的值为0
。但是,语句a["ext2"]
后的值为 1。当读取第 3 行时,该语句将返回false
。换句话说,我们已经看到$NF
了吗?当您用"is"或“否”回答这个问题时,将$NF
的计数加一。!a[$NF]++{print $NF}
::这结合了一切。它本质上指出,如果!a[$NF]++
返回true
,则print $NF
,但在打印增量a[$NF]
by one。 或者换句话说,如果表示扩展名 ($NF
) 的字段第一次出现,则打印该字段。如果它之前已经出现过,什么都不做
。
数组的递增很重要,因为它跟踪已经看到的内容。所以逐行会发生以下情况
foo.ext1 => $NF="ext1", a["ext1"] is 0 so print $NF and set a["ext1"]=1
bar.ext2 => $NF="ext2", a["ext2"] is 0 so print $NF and set a["ext2"]=1
spam.ext2 => $NF="ext2", a["ext2"] is 1 so do not print and set a["ext2"]=2
ham.ext3 => $NF="ext3", a["ext3"] is 0 so print $NF and set a["ext3"]=1
spam.ham.eggs => $NF="eggs", a["eggs"] is 0 so print $NF and set a["eggs"]=1
输出是
ext1
ext2
ext3
eggs
一般评论:
隐藏目录中没有任何扩展名的文件(例如
./path/to/awesome_filename_without_extension
或./path/to/.secret/filename_without_extension
) 或其完整路径的一部分打印出来,就好像它是扩展名一样。然而,结果意义不大,即/path/to/awesome_filename_without_extension secret/awesome_filename_without_extension
这最好解决为
find . -type f -exec basename -a '{}' + \ | awk -F. '((NF>1)&&(!a[$NF]++)){print $NF}'
此处 find 的输出直接由
basename
处理,它从文件名中剥离目录。 awk 行再检查一次,我们是否有超过 1 个字段(即是否有扩展名)。
关于linux - 获取不同的扩展名列表 Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48635628/