【leetcode】shell四道题的专栏含讲解

前言

本栏目主要是科普shell的一些基本使用,但题目比较少,做的不够过瘾(官方只有四道题)

专栏地址:leetcode:shell题目

但是这四道题的一些基本命令都比较常用,在笔试中的选择题遇到的概率比较高(因为下面的命令真的很有用=-=)推荐你看看

192. 统计词频(中等)

题目:

写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。

为了简单起见,你可以假设:

  • words.txt只包括小写字母和 ’ ’ 。
  • 每个单词只由小写字母组成。
  • 单词间由一个或多个空格字符分隔。

示例:

假设 words.txt 内容如下:

the day is sunny the the
the sunny is is

你的脚本应当输出(以词频降序排列):

the 4
is 3
sunny 2
day 1

说明:

不要担心词频相同的单词的排序问题,每个单词出现的频率都是唯一的。
你可以使用一行 Unix pipes 实现吗?


思路:

#tr 删除指定字符,-s为连续重复删除
#uniq删除重复出现的行 ,-c统计重复出现的次数
#sort 排序,-r主要是为了反转顺序,-n次数大于10的时候,代表按照数字排序,而不是ascii排序
#awk 输出打印,配合print函数,将其第一列和第二列互换

cat words.txt|tr -s ' ' '\n'|sort|uniq -c|sort -nr|awk '{print$2,$1}'

以下为注释:

  • cat 显示文本文件
  • tr 转换或删除文件中字符,配合-s参数缩减连续重复的指定单个字符

the
day
is
sunny
the
the
the
sunny
is
is

  • sort将其上面的排序
  • uniq检查以及删除重复出现的相邻行列,配合参数-c使用(每一列旁边显示重复出现的次数)
  • sort再次将其排序,主要是配合参数-r 相反顺序,为了让其最大的在第一个输出
  • awk 以及print 打印函数 将其第一列和第二列互换

除了以上的代码格式 还有另外一种替换方式:

xargs -n1,其作用为将所有航转换为当列显示

cat words.txt|xargs -n1|sort|uniq -c|sort -nr|awk '{print$2,$1}'

193. 有效电话号码(简单)

题目:

给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个单行 bash 脚本输出所有有效的电话号码。

你可以假设一个有效的电话号码必须满足以下两种格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)

你也可以假设每行前后没有多余的空格字符。

示例:

假设 file.txt 内容如下:

987-123-4567
123 456 7890
(123) 456-7890

你的脚本应当输出下列有效的电话号码:

987-123-4567
(123) 456-7890


思路:

关于正则的一些注意事项:

  • ^ 要求匹配的字符串是在行首
  • $ 要求匹配的字符串在行尾
  • {3} 前面的连续匹配三个数字

这道题的思路主要是正则表达式的配对

  • (xxx) xxx-xxxx 表示为 ^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$
  • xxx-xxx-xxxx 表示为 ^[0-9]{3}-[0-9]{3}-[0-9]{4}$

取两者 前面不一样的部分座位 并集,后面 公共部分 作为交集

#  (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)

# 加入-p的参数主要是为了配合使用perl的正则表达式用法

grep -P '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt 

也可使用awk打印输出,但是awk命令的正则表达式要放在"//“中间,所以首尾都有一个”/"

awk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt

194. 转置文件(中等)*

题目:

给定一个文件 file.txt,转置它的内容。

你可以假设每行列数相同,并且每个字段由 ’ ’ 分隔。

示例:

假设 file.txt 文件内容如下:

name age
alice 21
ryan 30

应当输出:

name alice ryan
age 21 30


思路:

类似编程模式,获取其列的个数,遍历列,输出行的内容

  • 具体获取列的个数:通过head -n 1表示获取指定行的内容,此处获取第一行的内容
    wc 获取个数,通过-w(word)参数获取其单词的个数
  • 遍历列的代码格式:for i in $(seq 1 $columns)
  • 循环输出每一列的内容,通过do,done
  • 输出的格式通过awk+print(shell对单引号和双引号,按从左到右的顺序成对匹配
    awk命令用单引号引起来,就是防止shell对其中内容进行解释)
    所以其命令为awk '{print $' "$i" '}' file.txt 拆分出来就是awk '{print $' 以及 "$i"以及'}',只有对其"$i" 进行了解释,其他都没有动
  • 通过xrag对其每一个按行显示

详情参考文档如下:
awk引用外部变量
⭐️ LeetCode解题系列 ⭐️ 194. 转置文件(Shell)题解

# 显示文本中的内容,head -n 1表示读取第一行,wc表示获取多少个频数,-w表示获取其当前行中的列有多少个
columns=$(cat file.txt | head -n 1 | wc -w)
for i in $(seq 1 $columns)
do
awk '{print $' "$i" '}' file.txt | xargs
done

195. 第十行(简单)

题目:

给定一个文本文件 file.txt,请只打印这个文件中的第十行。

示例:

假设 file.txt 有如下内容:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10

你的脚本应当显示第十行:

Line 10

说明:

  1. 如果文件少于十行,你应当输出什么?
  2. 至少有三种不同的解法,请尝试尽可能多的方法来解题。

思路:

  • tail -n +10 表示从第10行开始,文件如果不足十行不会输出
  • tail -n 10 表示现显示最后的十行

显示第10行开始的那一行

tail -n +10 file.txt|head -1

或者执行set -p(在当前输出到\n结束)

sed -n 10p file.txt

# 打印1到10行,则应该这么输出
set -n '1,10p' file.txt

或者使用awk直接打印输出

awk 'NR==10' file.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值