Weaving Wong

总觉得该写点啥...

嗨,我是Weaving,一名机器学习爱好者.


分享读书、学习、生活感悟

LeetCode shell 编程实践

统计词频

写一个 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 实现吗?

awk '{
    for(i = 1; i <= NF; i++){
        res[$i] += 1 #以字符串为索引,res[$i]相同的累计
    }
}
END{
    for(k in res){
        print k" "res[k]
    }
}' words.txt | sort -nr -k2  # n:按数值排序,r:倒序,k:按第2列排序
cat words.txt | tr -s ' ' '\n' | sort | uniq -c | sort -r | awk '{ print $2, $1 }'

tr-s:用目标字符串截断字符串,但只剩下一个实例(例如,多个空格)
sort:使相同的字符串连续,以便uniq能够完整和正确地计数相同的字符串。
Uniq-c:uniq用于过滤连续的重复行,
-c :表示计数排序
-r :-r表示按降序排列
awk'{print$2,$1}':以格式化输出

有效电话号码

给定一个包含电话号码列表(一行一个电话号码)的文本文件 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

grep -P '^(([0-9]{3}) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt
grep -P '^(\d{3}-|\(\d{3}\) )\d{3}-\d{4}$' file.txt
# -P 是采用perl语法进行匹配

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

转置文件

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

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

示例:

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

name age alice 21 ryan 30 应当输出:

name alice ryan age 21 30

# Read from the file file.txt and print its transposed content to stdout.
awk '{ #这个大括号里的代码是 对正文的处理
    # NF表示列数,NR表示已读的行数
    # 注意for中的i从1开始,i前没有类型
    for (i=1; i<=NF; i++){#对每一列
        if(NR==1){       #如果是第一行
            #将第i列的值存入res[i],$i表示第i列的值,i为数组的下标,以列序号为下标,
            #数组不用定义可以直接使用
            res[i]=$i;   
        }
        else{
            #不是第一行时,将该行对应i列的值拼接到res[i]
            res[i]=res[i] " " $i
        }
    }
}
# BEGIN{} 文件进行扫描前要执行的操作;END{} 文件扫描结束后要执行的操作。
END{
    #输出数组
	for (i=1; i<=NF; i++){
		print res[i]
	}
}' file.txt
transpose=`head -n1 file.txt | wc -w`   # wc是计数,head -n1 是前1行

for i in `seq 1 $transpose`             # sep 1 10 生成1到10的序列
do
    echo `cut -d' ' -f$i file.txt`      # cut -d " " -f1 以空格隔开,第1个区域
done

第十行

给定一个文本文件 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. 至少有三种不同的解法,请尝试尽可能多的方法来解题。
awk 'NR == 10' file.txt     # NR在awk中指行号

sed -n 10p file.txt         # -n表示只输出匹配行,p表示Print

tail -n+10 file.txt|head -1  # tail -n +10表示从第10行开始输出
最近的文章

MySQL——分组查询表内某字段最大值所在的记录

# 示例 CREATE TABLE orders(id VARCHAR(10),statu CHAR(1),goods_id VARCHAR(10),price DECIMAL(12,2)); INSERT INTO orders(id,goods_id,statu,price) VALUES('1','g','1',100);INSERT INTO orders(id,goods_id,statu,price) VALUES('2','g','1',200);INSERT INTO or...…

MySQL继续阅读
更早的文章

spark(1)- aggregate方法和fold方法总结

aggregate方法和fold方法总结最近在学习spark,理解这两个函数时候费了一些劲,现在记录一下。 rdd.fold(value)(func) 说到fold()函数,就不得不提一下reduce()函数,他俩的区别就在于一个初始值。 reduce()函数是这样写的:rdd.reduce(func)参数是一个函数,这个函数的对rdd中的所有数据进行某种操作,比如:val l = List(1,2,3,4)l.reduce((x, y) => x + y)对于这个x,它代指的是返...…

spark继续阅读