前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux常用命令面试题(1)

Linux常用命令面试题(1)

作者头像
小萌哥
发布2020-07-20 14:44:02
1.3K0
发布2020-07-20 14:44:02
举报

Linux常用命令是每个开发人员必须熟练掌握的,也是面试过程中经常被问到的知识点。下面给大家分享 Linux常用命令面试题 系列文章,持续更新,敬请关注。

1. 显示一个文件的第2000-5000行。
命令:
cat file | head -n  5000 | tail -n +2000  # 显示2000行到5000行
解析:

tail -n +2000 表示的是从2000行开始显示;

tail -n 2000 表示的是显示文件最后2000行,差别很大,注意灵活使用。

务必注意:head与tail的前后顺序。 如果将tail 放前面,如下命令: cat file | tail -n +2000 | head -n 5000 表示的是 : 从第2000行开始,共显示5000行,也就是2000~6999行!

2. 将当前目录下以".log"结尾且修改时间大于90天的5G以上的大文件删除。
命令:
find ./ -name "*.log" -type f -mtime +90 -size +10G -maxdepth 1 -print -exec rm {} \;
解析:
  • -name "*.log" : 按名称查找,如果忽略大小写,则用-iname,注意引号别丢;
  • -type f :文件类型限定为文件,目录是d
  • -mtime +90 :修改时间大于90天。-n指n天以内,+n指n天以前
  • -size +10G :文件size过滤
  • -maxdepth 1 :限制查找最大深度,当前目录是1
  • -print :将找到的文件以相对路径的形式打出来
  • -exec rm {} \; 找到的文件将执行删除命令,最后是"空格"+{}+"分号;"都不能省。
  • 补充:
  • 如果是删除文件,用rm -rf ;
  • 如果想要删除前确认,将" -exec rm {} \;"替换成"-ok rm {} \;"
3. 有两个文件a和b,如下所示,请统计两个文件的交集、差集。

文件a 1 2 1 3 4 2 文件b 1 4 2 5 6 1

命令:

方法1 : 使用comm实现,配合sort和uniq命令

# 交集
comm -12 <(sort a|uniq) <(sort b|uniq)
# 差集:a-b
comm -23 <(sort a|uniq) <(sort b|uniq)
# 差集:b-a
comm -13 <(sort a|uniq) <(sort b|uniq)

方法2:使用grep实现,结合 参数-vFf

# 交集
grep -Ff a b|sort|uniq
# 差集:a-b
grep -vFf b a
# 差集:b-a
grep -vFf a b
解析:

1. comm命令

  • comm比较的两个文件A和B,必须是排序和唯一(sorted and unique)的,所有要用sort|uniq进行预处理。
  • comm默认输出三列,第一列为是差集A-B,第二列是差集B-A,第三列为A交B。
  • comm命令参数:
  • -m m可以是1,2,3,表示的是不显示第m列,只显示剩余的两列。
  • -mn 同理,不显示第m列和第n列,只显示剩下的一列。
  • "<"表示输入重定向,即输入不从键盘读入,而是从文件输入或其它。从命令输入时括号不可省略。

comm缺点:待比较文件需要先(sort|uniq)预处理

2. grep命令

  • grep比较的两个文件不需要排序和去重,但是不能有空行,否则不能比较。
  • 空行可以用sed -i '/^$/d' A B去除。
  • -Ff参数是求交集,但是结果没有排序和去重,需要用sort|uniq处理下
  • -vFf是求差集,这里需要注意文件的先后顺序,可以这样记忆: 哪个文件在后,结果显示的是只包含在该文件中的内容 比如:grep -vFf b a的结果是差集b-a。

grep缺点:需要先对每个文件进行空行删除处理

4. 有下面一个文件,请统计每行中每个元素出现的次数并按指定格式输出:

文件内容: a a a b b b c c c d d d 输出格式: a:3 b:1 b:2 c:3 d:3

命令:
cat file|awk -F' ' '{delete a; for(i=1;i<=NF;i++) a[$i]++; for(i in a) printf i":"a[i]"\t"; printf "\n"}'
解析:

该命令的主体是一个awk语句:awk -F' ' '{}', 其中,-F指定每行的分隔符, '{}'是每行要执行的命令。

需要提醒的是awk、grep、sed这些文本处理命令,都是按行遍历处理的。

首先我们提取awk核心语句'{}'中的内容:

{delete a; for(i=1;i<=NF;i++) a[$i]++; for(i in a) printf i":"a[i]"\t"; printf "\n"}

根据分号提示,我们可以将其分为四个部分:

1. delete a;

先不管这个,看下一个

2. 遍历每行每个列元素,把每个列元素出现的次数记录下来。

for(i=1;i<=NF;i++) a[$i]++;

其中,NF表示每行的总列数,$i是该列具体内。 a[$i]++是建立一个数组(字典),其中,key为$i, value为$i的出现次数。 通过for循环,遍历每行的每个列,将各个列的出现次数进行了汇总求和。

3. 每行统计完之后,打印统计数组a

for(i in a) printf i":"a[i]"\t";

通过for循环,逐个打印该行统计字典a的每个itemprintf 是格式化输出,打印完不回车。

4. 该行统计结束后,最后要打印一个回车符,然后继续下一行的统计。

printf "\n"

那么问题来了,此时是不是应该将数组a中的元素清除??想一想,如果不清楚a的话,遍历后面行的时候,每个item会在前面统计次数的结果上继续累加!

也就是我们上面跳过的第1步 : deleta a;它的作用是:

每行开始统计前,都要清空上一行的统计数组a的内容,新行的统计结果会放到空的a中。

5. 有一个文件如下,请统计每个广告商的展示广告总数和成单总数。

文件内容: advertiserId:0001 displayNum:100 orderNum:2 advertiserId:0001 displayNum:300 orderNum:4 advertiserId:0003 displayNum:500 orderNum:12 advertiserId:0004 displayNum:200 orderNum:8 输出格式: 0001 400 6 0003 500 12 0004 200 8

命令:(虽然有点长,但是逻辑很清晰,请看解析拆解)
cat file|awk '{match($0,/advertiserId:([0-9]*) displayNum:([0-9]*) orderNum:(.*)/,a);print a[1],a[2],a[3]}'|awk '{a[$1][0]+=$2;a[$1][1]+=$3} END{for(i in a) print i,a[i][0],a[i][1]}'
解析:

该命令主要由两个awk通过管道连接组成,对每个awk分别讲解: (1)第一个awk:将所需要的字段匹配打印出来

通过执行第一个awk语句,可以输出下列格式:

0001 100 2 0001 300 4 0003 500 12 0004 200 8

awk '{match($0,/advertiserId:([0-9]*) displayNum:([0-9]*) orderNum:(.*)/,a);print a[1],a[2],a[3]}'

该部分的主体是两个函数:match匹配函数和print函数。

(1)match函数部分

格式:match(string,regex,array)

参数介绍

string是要匹配的字符串

regex是正则表达式

array是匹配出内容的存储数组

因此,回到我们的match匹配例子。

match($0,/advertiserId:([0-9]*) displayNum:([0-9]*) orderNum:(.*)/,a);

第1个参数我们使用$0,也就是一整行。

第2个参数是一个匹配表达式:

/advertiserId:([0-9]*) displayNum:([0-9]*) orderNum:(.*)/

表达式需要两个“/”作为start和end标志,后续需要用到的item需要用()括起来。

第3个参数是一个数组名称,我们用a表示,这样数组a就可以将前面的三个()里面的item存下来了。

(2)print部分

print a[1],a[2],a[3];

这个语句的作用就是:将每行统计数组a中的各个统计项打印出来。

总结:第一个awk的作用是将我们需要的字段匹配出来,并统计好,打印出来。

(2)第二个awk:根据advertiserId汇总各行

首先,重申一下第一个awk执行完之后的输出结果:

0001 100 2 0001 300 4 0003 500 12 0004 200 8

第二个awk的内容是:

awk '{a[$1][0]+=$2;a[$1][1]+=$3} END{for(i in a) print i,a[i][0],a[i][1]}'

主要包括两个部分: 每行执行语句和END{}结束语句。

(1)每行执行语句

{a[$1][0]+=$2;a[$1][1]+=$3} 

这里,可以把 a 理解为一个python字典,key是广告商ID,也就是第一个awk执行后输出结果的$1

value是一个数组,存储两个数据:

  • 第一个是广告展示数,对应$2
  • 第二个是广告成单数,对应$3

因此,通过执行上面的语句,可以将每个广告商的广告展示数和成单数进行汇总。

注意: 本题和第一题不同的是,不用再执行每一行时,清空a中的元素,因为本题是对所有行进行广告商维度的汇总统计,而不是统计完每行都要汇总一下。

(2) END{}结束语句

END{}语句的执行时机是:awk对所有的行遍历汇总完之后,汇总结果保留在字典a中。

通过执行下面语句,可以将汇总字典a中的各项内容清晰打印出来:

END{for(i in a) print i,a[i][0],a[i][1]}

其中,i是广告商ID,a[i][0]是该广告商的广告展示数,a[i][1]是成单数。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法研习社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 显示一个文件的第2000-5000行。
    • 命令:
      • 解析:
      • 2. 将当前目录下以".log"结尾且修改时间大于90天的5G以上的大文件删除。
        • 命令:
          • 解析:
          • 3. 有两个文件a和b,如下所示,请统计两个文件的交集、差集。
            • 命令:
              • 解析:
              • 4. 有下面一个文件,请统计每行中每个元素出现的次数并按指定格式输出:
                • 命令:
                  • 解析:
                  • 5. 有一个文件如下,请统计每个广告商的展示广告总数和成单总数。
                    • 命令:(虽然有点长,但是逻辑很清晰,请看解析拆解)
                      • 解析:
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档