192. 统计词频

提交记录

解1:

1
2
# Read from the file words.txt and output the word frequency list to stdout.
awk '{for(a=1;a<=NF;a++) print $a}' words.txt | sort | uniq -c | sort -nr | awk '{print $2,$1}'

知识点

awk分割出的每一行各字段分行打印

1
awk '{for(a=1;a<=NF;a++) print $a}' words.txt

注:awk里的print默认打印之后输出一个换行,若不换行用printf

统计文本文件中重复出现的行列

uniq+sort结合使用:

1
sort test.txt | uniq -c

注:-c原理是接下来的字符串相同则加一,如果不进行sort排序的话将无法统计数目。

降序排列

1
sort -r

193. 有效电话号码

提交记录

解1:

1
2
# Read from the file file.txt and output all valid phone numbers to stdout.
awk '/(^[0-9]{3}-[0-9]{3}-[0-9]{4}$)|(^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$)/' file.txt

解2:

1
2
# Read from the file file.txt and output all valid phone numbers to stdout.
sed -n -r '/(^[0-9]{3}-[0-9]{3}-[0-9]{4}$)|(^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$)/p' file.txt

解3:

1
2
# Read from the file file.txt and output all valid phone numbers to stdout.
sed -n -r '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/p' file.txt

知识点

正则表达式实现或运算

1
(PatternA|PatternB)

注意:如果是需要完全匹配PatternA或是完全匹配PattenB,则^$在两个Pattern语句里都需要写,而不是写在括号外面。

参考:正则表达式实现与或非

正则表达式空格匹配

若要匹配任何空白字符,包括空格、制表符、换页符等等:\s,等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。

若只需要匹配单个空格,直接输入空格即可:

正则表达式中的\dawk里无法识别

改为[0-9]

sed使用扩展类正则

必须加上参数-r

正则表达式学习参考

一篇搞定:正则表达式中限定符与定位符的灵活使用

SHELL编程正则表达式,这一篇就够了

在线测试工具&常用正则表达式

194. 转置文件

提交记录

解1(逻辑没问题,但是超出时间限制):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Read from the file file.txt and print its transposed content to stdout.
M=`awk '{print NR}' file.txt | tail -n 1` #获取行数
N=`awk '{print NF}' file.txt | tail -n 1` #获取列数
if [ $M -eq 1 ];then
awk '{for(a=1;a<=NF;a++) print $a}' file.txt
else
for ((i=1;i<=$N;i++))
do
for ((j=1;j<=$M;j++))
do
awk -v J=$j -v I=$i 'NR==J{printf $I}' file.txt
if [ $j -lt $M ];then
echo -e ' \c'
fi
done
echo
done
fi

解2(利用awk数组):

1
2
# Read from the file file.txt and print its transposed content to stdout.
awk '{for(a=1;a<=NF;a++) array[NR,a]=$a;} END{for(i=1;i<=NF;i++) {for(j=1;j<NR;j++) printf array[j,i]" "; print array[j,i];} }' file.txt

解3(主要是xargs跟这道题的格式绝配):

1
2
3
4
5
6
# Read from the file file.txt and print its transposed content to stdout.
N=`awk '{print NF}' file.txt | tail -n 1` #获取列数
for ((i=1;i<=$N;i++))
do
cut -d " " -f $i file.txt | xargs
done

知识点

echo输出不换行

1
echo -n '输出的内容'

1
echo -e '输出的内容\c'

参考:echo不换行输出的两种方式

把shell变量传给awk

1
awk -v var=value ... #value可以调用前面shell中定义的变量,用上$

注:一个-v后接一个变量赋值,若要传多个变量值,需要接着用多个-v

awk流程控制(iffor循环)

参考:linux shell awk 流程控制语句(if,for,while,do)详细介绍

awk数组

注:awk数组创建时的下标可以直接调用awk脚本里的变量作为索引,不用加引号变为字符串,读数组值时同理。

参考:linux awk 数组和循环菜鸟教程:AWK 数组

awk参考学习

号称三剑客之首的awk,开始秀!

xargs:把多行打印到一行里

参考:菜鸟教程:Linux xargs 命令

195. 第十行

提交记录

解1:

1
2
3
4
5
6
7
# Read from the file file.txt and output the tenth line to stdout.
line=`awk '{print NR}' file.txt | tail -n 1`
if [ $line -lt 10 ];then
:
else
sed -n '10p' file.txt
fi

解2:

1
2
3
4
5
6
7
# Read from the file file.txt and output the tenth line to stdout.
line=`awk '{print NR}' file.txt | tail -n 1`
if [ $line -lt 10 ];then
:
else
awk 'NR==10' file.txt
fi

知识点

健全性

原题里的说明里有一句话:“如果文件少于十行,你应当输出什么?”,因此需要一个if来判断文件行数是否少于10行

获取文件行数

1
awk '{print NR}' file.txt | tail -n 1

参考:Shell脚本统计文件行数的8种方法

把命令结果作为值赋给自定义变量(两种方式)

1
2
3
#全程没有空格,变量名左边不用加$
变量名=`命令`
变量名=$(命令)

虽然上述两种方式都可以在Shell脚本中得到命令运行的结果,但是有一点是不一样的,那就是反引号执行命令不支持嵌套,不能实现反引号中再出现反引号,而 $(command)的方式是支持嵌套的。

参考:Shell脚本中获取命令运行结果、特殊变量使用、条件判断等常用操作

[ condition ]打印出条件判断的结果

在终端里执行完[ condition ]之后执行echo $?,若打印出0则结果为true,打印出1则结果为false。

echo不打印任何信息

1
2
: #单个冒号,不执行任何操作,相当于终端里摁下enter键
echo #echo后面不加任何变量,打印出一个空行

参考:shell不打印

输出文件中的第10行

1
2
sed -n '10p' file.txt
awk 'NR==10' file.txt

参考思路

LeetCode上稀缺的四道shell编程题解析