<commit_before>---
layout: post
title: 数据分析中的命令行工具（1）
subtitle:   Linux Shell 内置命令
date:       2017-01-06
author:     "Scott"
header-img: "img/160403-debian.png"
catalog:    true
tags:
    - Linux
---

自 16 年 9 月开始转岗「数据分析师」，已近 4 月，数据分析的前提是数据清洗和整理，在诸多重复性工作中，命令行无疑帮了大忙，多数任务用 Python 等编程语言得写小会代码，而命令行通常一两行就能解决，这篇文章是我最常用的系统内置命令介绍，Mac 系统可参考 [这个答案](http://apple.stackexchange.com/questions/69223/how-to-replace-mac-os-x-utilities-with-gnu-core-utilities) 下载 GNU 工具。

## head & tail 查看数据

```
head -n Number filename
tail -n Number filename
```

上面 head 和 tail 的基本用法相信很多人知道，但如果你想去除某些行，打印其他呢？

```
$ seq 20 | head -n -5
```

这条命令将去除最后5行，打印 1-15 行，同理：

```
$ seq 20 | tail -n +6
``` 
将打印后15行，去除了前 5 行，记得这里数字 +1 了。

跟 body 配合一起用非常方便，如看看 coca 1000-2000 的词频

```
$ coca20k head -n 2000 coca20k_source.csv | body tail -n +1001 | head -n 5
rank,words,speech,frequency,dispersion
1001,method,n,42667,0.88 A
1002,sign,v,39418,0.95
1003,somebody,p,41639,o.90 S
1004,magazine,n,39197,0.96
```

body 的用处在于保存头部处理数据。


## sort & uniq 排序和唯一

在我之前的文章有提过，`sort` 排序有这些参数

- `-n` 按数字进行排序
- `-d` 按字典序进行排序
- `-r` 逆序排序
- `-k` N 指定按第 N 列排
- `-t` 指定分割符号，跟 `body` 配合使用时会出错，不建议用
    - 纯粹的 `'\t'` 或 `' '` 分割，可以直接用sort，无须指定
    - 而两者混合的情况，则需 `-t$'\t'` 做 tab 分割 排序，空格则无须用 `$` 特别强调。

为了看清一个数据的近似分布，可能会想画个直方图，若嫌开启 Python、R 太麻烦，其实命令行也可以搞定基本的。

```
$ cat sample.txt
January
January
February
October
January
March
September
September
February
```

```
$ cat sample.txt | sort | uniq -c | sort -rk1
      3 January
      2 September
      2 February
      1 October
      1 March
```

uniq 一定得和 sort 搭配用，如果没有第一个 sort，频数统计便会出错，第二个 sort 的 `-r` 表示反向，`-k` 表示列，`-1`表示频数排序。


## tr 转换

```
$ tr -s [set1]  # 压缩
$ tr -d [set1]  # 删除特定字符
$ tr [set1] [set2]  # 替换
```


## grep 文本内搜索

查看不包含

```
$ grep -v scott /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
......
```

查看不包含的行数

```
$ grep -cv scott /etc/passwd/
43
```

查找时忽略大小写

```
$ grep -i scott /etc/passwd
```

在一个路径下查找匹配模式下的文件, 这个很常用，比如忘记自己的代码在哪个文件了。

```
grep -rnw path -e 'patterns'  # 模式
grep -rnw /home/scott/AnalyzedNotes -e 'FontProperties'  # 实例
```<commit_msg>Update "grep"<commit_after>---
layout: post
title: 数据分析中的命令行工具（1）
subtitle:   Linux Shell 内置命令
date:       2017-01-06
author:     "Scott"
header-img: "img/160403-debian.png"
catalog:    true
tags:
    - Linux
---

自 16 年 9 月开始转岗「数据分析师」，已近 4 月，数据分析的前提是数据清洗和整理，在诸多重复性工作中，命令行无疑帮了大忙，多数任务用 Python 等编程语言得写小会代码，而命令行通常一两行就能解决，这篇文章是我最常用的系统内置命令介绍，Mac 系统可参考 [这个答案](http://apple.stackexchange.com/questions/69223/how-to-replace-mac-os-x-utilities-with-gnu-core-utilities) 下载 GNU 工具。

## head & tail 查看数据

```
head -n Number filename
tail -n Number filename
```

上面 head 和 tail 的基本用法相信很多人知道，但如果你想去除某些行，打印其他呢？

```
$ seq 20 | head -n -5
```

这条命令将去除最后5行，打印 1-15 行，同理：

```
$ seq 20 | tail -n +6
``` 
将打印后15行，去除了前 5 行，记得这里数字 +1 了。

跟 body 配合一起用非常方便，如看看 coca 1000-2000 的词频

```
$ coca20k head -n 2000 coca20k_source.csv | body tail -n +1001 | head -n 5
rank,words,speech,frequency,dispersion
1001,method,n,42667,0.88 A
1002,sign,v,39418,0.95
1003,somebody,p,41639,o.90 S
1004,magazine,n,39197,0.96
```

body 的用处在于保存头部处理数据。


## sort & uniq 排序和唯一

在我之前的文章有提过，`sort` 排序有这些参数

- `-n` 按数字进行排序
- `-d` 按字典序进行排序
- `-r` 逆序排序
- `-k` N 指定按第 N 列排
- `-t` 指定分割符号，跟 `body` 配合使用时会出错，不建议用
    - 纯粹的 `'\t'` 或 `' '` 分割，可以直接用sort，无须指定
    - 而两者混合的情况，则需 `-t$'\t'` 做 tab 分割 排序，空格则无须用 `$` 特别强调。

为了看清一个数据的近似分布，可能会想画个直方图，若嫌开启 Python、R 太麻烦，其实命令行也可以搞定基本的。

```
$ cat sample.txt
January
January
February
October
January
March
September
September
February
```

```
$ cat sample.txt | sort | uniq -c | sort -rk1
      3 January
      2 September
      2 February
      1 October
      1 March
```

uniq 一定得和 sort 搭配用，如果没有第一个 sort，频数统计便会出错，第二个 sort 的 `-r` 表示反向，`-k` 表示列，`-1`表示频数排序。


## tr 转换

```
$ tr -s [set1]  # 压缩
$ tr -d [set1]  # 删除特定字符
$ tr [set1] [set2]  # 替换
```


## grep 文本内搜索

查看不包含

```
$ grep -v scott /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
......
```

查看不包含的行数

```
$ grep -cv scott /etc/passwd/
43
```

这点 csvgrep 不太一样，同样是 `--invert-match`, csvgrep 用的是 `-i` 作为简化参数。

查找时忽略大小写

```
$ grep -i scott /etc/passwd
```

在一个路径下查找匹配模式下的文件, 这个很常用，比如忘记自己的代码在哪个文件了。

```
grep -rnw path -e 'patterns'  # 模式
grep -rnw /home/scott/AnalyzedNotes -e 'FontProperties'  # 实例
```
{'fraction_non_alphanumeric': 0.16816344858554108, 'fraction_numerical': 0.0570273911091154, 'mean_word_length': 3.5598771750255884, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1074403', 'n_tokens_mistral': 2899, 'n_tokens_neox': 2892, 'n_words': 441}