共计 3495 个字符,预计需要花费 9 分钟才能阅读完成。
最近在面试中碰到了一些对于 linux 下一些简略命令的操作和 awk sed 等文本编辑器的应用,借助力扣上 4 道 shell 题目进行学习,当然也参考一些他人的答案作为总结,欢送补充交换,如有侵权,分割删除
问题一:第十行(考查打印特定行)
示例:
假如 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. grep -n ""file.txt | grep -w'10' | cut -d: -f2
2. sed -n '10p' file.txt
3. awk '{if(NR==10){print $0}}' file.txt
然而思考到阐明中行数有余 10 的状况解决,能够做如下解决:
row_num=$(cat file.txt | wc -l)
echo $row_num
if [$row_num -lt 10];then
echo "The number of row is less than 10"
else
awk '{if(NR==10){print $0}}' file.txt
fi
补充:其中文件行数 row_num 能够应用如下几种形式获取
1. awk '{print NR}' file.txt | tail -n1
2. awk 'END{print NR}' file.txt
3. grep -nc "" file.txt
4. grep -c "" file.txt
5. grep -vc "^$" file.txt
6. grep -n ""file.txt|awk -F:'{print '}|tail -n1 | cut -d: -f1
7. grep -nc "" file.txt
8. sed -n "$=" file.txt
9. wc -l file.txt
10 file.txt
cat file.txt | wc -l
10. wc -l file.txt | cut -d' ' -f1
问题二:无效的电话号码(考查正则表达式)
给定一个蕴含电话号码列表(一行一个电话号码)的文本文件 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
准备常识:
1. 特殊字符表白:
2. 限定符表白:
留神: 表含意中的呈现次数:限定符后面字符的呈现次数。
3. 定位符:
对于 grep
的 4 中写法:
1. cat file.txt | grep -P "^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$|^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
2. grep -P '^(\(\d{3}\) |\d{3}-)\d{3}-\d{4}$' file.txt
3. grep -P '^([(]\d{3}[)] |\d{3}-)\d{3}-\d{4}$' file.txt
4. grep -E '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt
留神:""
不要丢了,其中的空格,()
是一般字符," "
不要丢了 ^
:示意行首,以 … 开始,这里示意以(xxx) 或者 xxx- 开始,留神空格()
:抉择操作符,要么是([0-9]{3}),要么是[0-9]{3}-|
:或者连贯操作符,示意或者[]
:单字符占位,[0-9] 示意一位数字 {n}
:匹配 n 位,[0-9]{3} 匹配三位间断数字$
:示意行尾,完结
对于 awk '/ 正则表达式 /{print $0}'
的 3 中写法:
1. awk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt
2. gawk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt
3. awk '/^\([0-9]{3}\)\s[0-9]{3}\-[0-9]{4}$|^[0-9]{3}\-[0-9]{3}\-[0-9]{4}$/{print $0}' file.txt
其中 3 中的 \s
示意空格
问题三:无效词频
写一个 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
办法一:
解题思路:
取出每个单词; NF
= 一行有多少列, for
循环一个一个取出来, 每行打印一个
把雷同的单词排在一起: sort
合并雷同的单词, 并标记数量: uniq -c
; c
代表 count
依照数字大小降序排列: sort
排序; -$1
依照 $1
count 来排序; -r
降序
先打印单词, 再打印数字: awk print $2,$1
代码:
awk '{for(i=0;i<NF;i++){print $(i+1)}}' words.txt |sort|uniq -c|sort -$1 -r|awk '{print $2,$1}'
办法二:
解题思路:xargs
宰割字符串 -n 1
示意每行输入一个 能够加 -d
指定宰割
要应用 uniq
统计词频须要被统计文本雷同字符前后在一起,所以先排序 uniq -c
示意同时输入呈现次数 sort -nr
其中-n
示意把数字当做真正的数字解决 (当数字被当做字符串解决,会呈现 11 比 2 小的状况)
代码:
cat words.txt | xargs -n 1 | sort | uniq -c | sort -nr | awk '{print $2" "$1}'
办法三:
获取 words.txt 的内容
将空格换成换行符,让每一个单词独自成为一列
依据字母程序进行排序
应用 uniq -c
统计频次
逆序排序
过滤空的字符,并将后果输入
代码:
cat words.txt | tr '''\n'| sort | uniq -c | sort -r | awk'$2!=""{print $2" "$1}'
问题四:转置文件
给定一个文件 file.txt,转置它的内容。
你能够假如每行列数雷同,并且每个字段由 ‘ ‘ 分隔.
示例:
假如 file.txt 文件内容如下:
name age
alice 21
ryan 30
该当输入:
name alice ryan
age 21 30
附上感觉特地清晰的一篇解说:
链接
以下为博客内容:
awk 命令:
awk 是一个报告生成器,它领有弱小的文本格式化的能力。它是由 Alfred Aho、Peter Weinberger 和 Brian Kernighan 这三个人发明的,awk 由这个三个人的姓氏的首个字母组成。
awk 的根本语法是 awk [options] 'Pattern{Action}' file
。
从一个最简略的命令作为 start,省略 [options] 和 Pattern,将 Action 设置成最简略的 print:
$ echo abc > test.txt
$ awk '{print}' test.txt
abc
这就是最最简略的 awk 用法:应用 awk
命令对文本 test.txt(的每一行)进行解决,解决的动作是print
。
解法:
awk '{for (i=1;i<=NF;i++){if (NR==1){res[i]=$i
}
else{res[i]=res[i]" "$i
}
}
}END{for(j=1;j<=NF;j++){print res[j]
}
}' file.txt
解析:
awk 是一行一行地解决文本文件,运行流程是:
- 先运行 BEGIN 后的{Action},相当于表头
- 再运行 {Action} 中的文件解决主体命令
- 最初运行 END 后的 {Action} 中的命令
有几个常常用到的 awk
常量:NF
是以后行的 field 字段数;NR
是正在解决的以后行数。
留神到是转置,如果原始文本有 m 行 n 列(字段),那么转置后的文本应该有 n 行 m 列,即原始文本的每个字段都对应新文本的一行。咱们能够用数组 res 来贮存新文本,将新文本的每一行存为数组 res 的一个元素。
在 END 之前咱们遍历 file.txt 的每一行,并做一个判断:在第一行时,每碰到一个字段就将其按程序放在 res 数组中;从第二行开始起,每碰到一个字段就将其追加到对应元素的开端(两头增加一个空格)。
文本处理完了,最初须要输入。在 END 后遍历数组,输入每一行。留神 printf 不会主动换行,而 print 会主动换行。