6.NULL Video Note
好的工具总是能带来高的效率
VIDEO 1 The Shell
cd -
将会在和上一次cd的目录来回切换rm
命令默认非递归的删除,因此删除目录时需要加上-r参数(recursive),才能完整地将目录下的文件删除;而rmdir只能删除空目录- 解释一下常用命令的含义
pwd
(print work directory),cd
(change directory) - -表示当前没有允许的权限。d表示目录,注意目录的x位表示当前能够访问该目录的内容,且需要保证当前目录的父目录都含有x位才能访问。
- redirect, < 表示重定向输入, > 表示重定向输出. Some example:
1
2
3
4
5
6
7
8missing:~$ echo hello > hello.txt
missing:~$ cat hello.txt
hello
missing:~$ cat < hello.txt
hello
missing:~$ cat < hello.txt > hello2.txt
missing:~$ cat hello2.txt
hello>>
表示追加(append) ctrl+L
清空终端的命令,返回到顶部。tail -n
将数据中的末尾n行显示出来。- pipe,将两个不相关联的程序连接起来通过input/output连接起来,管道的左边作为一个input, 管道的右边作为一个output。
$
表示当前运行在用户模式下;#
表示当前运行在系统模式下,可以通过命令sudo su
来打开root下的terminal.- xdg-open命令可以打开文件对应的格式
- double quotes: backslash,
\
前面加个!
就不会被默认移除 - shebang是由脚本开头的字符数字符号和感叹号
#!
组成的字符序列。当带有shebang的文本文件被用作类Unix操作系统的”可执行文件”时,程序加载器机制将文件初始行的其余部分解析为”解释器指令”。它告诉内核用什么来运行此脚本(比如说python or shell?)
VIDEO 2 Shell Tools and Scripting
- different from the single quote
(')
and double quote(")
. echo “”中解析出变量放变量(用$
符号来表示)。而单引号不会解析变量。 $1
到$9
表示argv中第一个到第九个参数$0
表示脚本的名字$_
(undersocre)表示上一个command的最后一个参数$?
(question mark)获取上一个command的error code(一般值为0
表示ok,1
表示执行出错)。$#
(hash)表示参数的个数$$
表示当前进程的ID$@
表示所有参数。
!!
(bang)代替上一次执行过的command,比如说创建一个目录mkdir ..
没有权限,这时候只需要sudo !!
, 就会默认表示sudo mkdir ..
从而减少了一些重复性的工作。- ;(semicolon)分号可以连接任何命令行。
false ; echo "haha"
- 脚本中变量用双引号引起来
"$1"
. - 执行脚本
source ..
- globbing, *(asterisk), {}(curly braces)
tldr
(too long, don’t read), 精简版带example的mantest
, 查看man手册- 查找文件:
find
查看man手册1
2
3
4
5
6
7
8
9
10
11
12# 查找所有名称为src的文件夹
find . -name src -type d
# 查找所有文件夹路径中包含test的python文件
find . -path '*/test/*.py' -type f
# 查找前一天修改的所有文件
find . -mtime -1
# 查找所有大小在500k至10M的tar.gz文件
find . -size +500k -size -10M -name '*.tar.gz'
# 删除全部扩展名为.tmp 的文件
find . -name '*.tmp' -exec rm {} \;
# 查找全部的 PNG 文件并将其转换为 JPG
find . -name '*.png' -exec convert {} {}.jpg \;- fd, find的替代物
locate
, 只能通过文件名,但速度很快。locate(1)当您只是尝试按名称查找特定文件时会更好,该文件您知道存在,但您只是不记得它的确切位置。find(1)当您有一个重点领域需要检查时,或者当您需要其众多优势中的任何一个时,效果会更好
shellcheck
检查shell脚本的语法。- 查找代码:
- 查找shell命令:
history
Ctrl+R
, backward search. 搭配fzf
- 文件夹导航:
tree
broot
- nnn, 需要接下来去学习
- shell中使用变量需要加
""
(double quote), 当变量中含有命令时需要加括号比如"$(pwd)"
- 进行比较时需要加
[[]]
双括号,比如说if [[ n -eq 12 ]]; then
, 注意括号左右要有空格否则出错。 - globbing
Exercise2
ls
- 所有文件(包括隐藏文件
ls -a
- 文件打印以人类可以理解的格式输出 (例如,使用454M 而不是 454279954)
ls -hl
- 文件以最近访问顺序排序
ls -clt
- 以彩色文本显示输出结果
ls --color=always
- 所有文件(包括隐藏文件
设计一个自动化shell。marco函数保存当前工作目录pwd到home目录的一个log文件中,polo函数通过打开log文件中的路径cd跳到之前所保存的目录中。
方法一:
1
2
3
4
5
6
7
8
9
10
11
marco() {
echo "$(pwd)" > "$HOME/marco_history.log"
echo "save pwd $(pwd)"
}
polo() {
cd "$(cat $HOME/marco_history.log)"
}export
可以增加、修改或删除环境变量,仅效力于该次登陆的操作,和第一种方法的时效类似。方法二:
1
2
3
4
5
6
7
marco() {
export MARCO=$(pwd)
}
polo() {
cd "$MARCO"
}shell表达式计算的格式为两个
(())
以及一些逻辑表达式的规范见此处。关于给的test中的语句中>&2
以及一些重定向的问题此处给出了答案。>&2
表示2
是个文件描述符,不是文件名
, 因为重定向的对象是文件名;&>
则表示同时发送,比如1&>2
表示标准输出和标准错误同时输出。for循环的格式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
count=1
chmod u=rwx ./test.sh
while true
do
./test.sh 2> out.log
if [[ $? -ne 0 ]]; then
echo "failed after $count times"
cat out.log
break
fi
((count++))
doneshellcheck建议增加一行
mycmd=$?
, 用mycmd
来代替$?
利用xargs命令完成一些操作。xargs命令将标准输入的内容作为参数。此处有关于
find
后的/
的作用,目的是方便为了遇到换行符\n
停止解析??tar
命令,压缩文件tar -czvf
, 解压文件tar -xzvf
,-c
表示创建备份文件,-x
表示从备份文件中还原文件。-f
表示指定备份文件,-v
表示显示verbose,-z
表示--gzip
或--ungzip
通过gzip
指令处理备份文件。xargs
的-d
参数后面跟字符表示修改xargs的分隔符(默认为空白字符tab、空格、换行符)。方法一,
xargs -d '\n'
指定输入遇到换行符结束:1
find -name '*.html' -type f | xargs -d '\n' tar -cxzf html.zip
方法二,
find -print0
打印文件名到标准输出后后面自动跟个null
;xargs -0
输入遇到null
则终止代替空格:1
find -name '*.html' -type f -print0 | xargs -0 tar -cxzf html.zip
找出当前文件夹下最近使用的文件, 并按照最近使用的时间列出文件
1
find type -f | xargs ls -tl | head-1
VIDEO 3 Editors(Vim)
v
进入可视化模式;V
进入可视化行模式;^v
(Ctrl + v
)进入可视化块模式- Vim大量使用
Esc键
,因此建议将大小写锁定键
设置为Esc键
, 可以在ubuntu下使用gnome-tweaks来配置交换修改大小写和Esc, 这里面同样介绍了VScode下的配置 - Vim 会维护一系列打开的文件,称为“缓存
buffer
”。一个 Vim 会话包含一系列标签tab
页,每个标签页包含 一系列窗口(分隔面板)。每个窗口显示一个缓存。 :qa
全部退出,:wq
等价于:x
:tabnew
;:e <文件名>
打开要编辑的文件w
移动一个单词b
回退一个单词e
移动到单词末尾, 可以搭配a
在光标之后插入文本。^
移动到行首字符$
移动到行尾字符0
移动到行首字符前^U
上翻页^D
下翻页gg
移动到最后一行- 输入
number
+G
则直接跳转到文件中的某一指定行。若不输入number
则直接跳到文件第最后一行。 H
屏幕首行M
屏幕中间L
屏尾巴行
- [
f
|F
|t
|T
][alpha], find和to功能来找到相应的字母 ^g
显示当前编辑文件中当前光标所在行位置以及文件状态信息。u
undo,U
撤销在一行中做出的所有改动 ;^r
redod
操作会将删除的内容放入vim中的寄存器中, 以便p
操作时粘贴。de
删除从光标处到单词尾dw
删除一个单词d
+上hjkl
方向可以删除需要的内容
c
change,功能类似于d
,只是操作c
会进入insert
模式- 在词尾插入
e
移动到词尾,随后a
在当前词尾插入 x
删除当前光标所处的字符, 如果在可视模式下就删除选中部分r
replace, 如ra
将当前字符替换为a;R
则可以连续替换多个字符。y
yank,p
paste,yw
copy one word, 都可以搭配可视化v
来使用。~
改变字母的大小写[num[h|j|k|l]
, 如4j
向下移动四次- modifier,
i
指的是inner
,a
指的是around
ci(
改变当前括号内的内容ci[
改变当前方括号内的内容da'
删除一个单引号字符串,包括周围的单引号
%
在配对的括号(parenthese)如:), ], }
之间来回切换。在程序调试时用来找不配对的括号是很有用的。/
后紧随一个字符串是在当前所编辑的文档中正向查找
改字符串;?
则与/
相反,是反向查找。:set ic
可以忽略大小写(Ignore Case
)会在接下来的查找中持续,:set noic
则忽略大小写;:set hls
搜索时设置高亮显示, 移除匹配项的高亮显示nohlsearch
;:set is
(incsearch)查找短语时显示部分匹配,:set noic
。- 每日一个vim小技巧
- 安装并配置插件
- Windows下映射CapsLock到ESC需要用到
autohotkey
脚本工具,添加语句Capslock::Esc
即可 ^o
回退到光标之前的位置,^i
跳转到较新的位置。s
is substitution. The first argument is search string, the second is replacement string.- 输入
:s/old/new
则只将光标所在行的第一个串old
修改为new
- - 输入
:s/old/new/g
则将全行的匹配串old
修改为new
。 :%s/old/new/g
则替换整个文件中的每个匹配串。:%s/old/new/gc
则会在替换时询问。:#,#s/old/new/g
其中#, #
代表的是替换操作的若干行中首尾两行的行号
- 输入
- 在vim内执行外部命令的方法,输入
:!
然后紧接着输入外部的shell
命令,如::!ls
,回车结束显示。 - 可以搭配可视模式将部分内容
:w <filename>
写到文件名中。 - 将磁盘文件内容提取到当前光标行
:r <filename>
. :sp
分割窗口,^w ^w
(double w)在窗口之间来回切换.F1
或者:help
打开帮助文档。下面这些参数可以得到该主题的帮助:help w
:help c_CTRL-D
:help insert-index
:help user-manual
,阅读Vim的用户手册。
.
(period)会完成重复性的工作。- vim命令的补全功能,例如输入
:e
, 然后按下^D
键, Vim会显示以e开始的命令的列表, 接着按下<tab>键
会自动自动补全命令。 q:
|q?
查看vim中的历史命令- 从vim8.0版本开始安装插件只需要将插件
git clone
到~/.vim/pack/vendor/start/
文件里就行。
Exercise3
vimtutor
- 创建文件
~/.vimrc
能够获得更多的特性。了解更多信息可以输入:help vimrc-intro
- 文件中注释使用
"
set nocompatible
从默认的Vi
兼容模式切换到激活Vim
的功能。如果vimrc
文件存在它就会默认设置nocompatible
, 包含这一条语句是为了以防以一些别的方式加载配置文件。syntax on
打开语法高亮set shortmess+=I
禁止Vim默认的启动信息:intro
,也就是解释vim的版本,以及该如何使用。set number
在vim中显示行数set relativenumber
显示与当前行的行号和与其相对的行号,其实set number
也可以不用加了set laststatus=2
在vim底部显示当前状态。2
表示不管存在几个窗口总是显示状态栏。set backspace=indent,eol,start
。设置backspace的属性,感觉好像vim兼容了对默认情况,经过测试这一行语句似乎没有什么实质性的作用。set hidden
可以告诉Vim你拥有未显示在屏幕上未保存的工作, 多一条提示信息。set ignorecase
不区分大小写set smartcase
只能在ignorecase
,它会使得区分大小写更智能。incsearch
使用/
搜索时会实时搜索,而不是等到Enter键按下时才进行搜索。nmap Q <Nop>
对按键Q的解绑操作,按键Q会进入Ex mode,<Nop>
意为无操作, 且nmap
和nnoremap
是等价的。nmap
是在Normal模式下使用,详情可见:h map-modes
。set noerrorbells visualbell t_vb=
, disable Vim的bell beeping。set mouse+=a
鼠标支持, 方便进入可视化选择。a
表示all previous modes。应用在vim中的所有五个模式。nmap <Left> :echoe "Use h"<CR>
来使用户养成在Normal模式下使用h来左移的习惯。imap <Left> <ESC>:echoe "Use h"<CR>
来使用户养成在Insert模式下使用h来左移的习惯,若在Insert模式下使用方向键Left,则回到Normal模式并提示信息”Use h”。因为Vim中的命令行换行是以CR
来结尾的(也就是敲完命令需要敲回车换行)才能执行该echo命令回显信息,echoe
回显的是错误信息,会加上红色高亮。
- 创建文件
如果创建多级目录的路径不存在则自动创建
mkdir -p
使用参数p
。安装和配置插件内含帮助文档 ctrlp.vim^P
打开模糊搜索c-d
切换搜索路径和文件的模式c-t
打开该文件作为新的tab;c-v
打开该文件分割列;c-x
打开该文件分割行; 个人认为这些tmux都可以替代。c-n
和c-p
选择next/previous在ctrlp中的搜索记录- 在ctrlp中输入
:help ctrlp-mappings
查看更多映射的帮助 - 查找到文件后加
:25
即可跳到该文件的25行
使用Chrome上的
vimium
有关Vim的插件。j
和k
上下移动网页,d
和u
以翻页的形式上下移动网页,h
和l
左右移动网页- 同样可以像vim一样前缀加上数字,比如
4j
等。也可以gg
跳至网页头和G
跳至网页尾 f
通过标签打开当前网页超链接到当前的tab上,F
则打开到新的tab上。- 当前tab历史的前进
L
和回退H
- 在打开的网页tab之间切换,上一个
J
, 下一个K
- 关闭当前标签页
x
,X
恢复关闭的tab - 在历史标签中搜索
o
,ESC
退出 - 若标签页太多,可以使用
T
在已有的标签之中搜索,ESC
退出 ?
打开Vimium
的帮助文档。r
(Reload)刷新当前网页yy
将当前的URL复制到剪切板,p
将剪切板上的URL在当前tab中打开,P
则在新的tab中打开gi
将光标焦距到当前网页的第一个输入栏(即搜索栏)b
搜索书签打开到当前tab,B
打开到新的tab中/
在当前网页中使用匹配, 搭配n
和N
t
创建新的tabalt+p
,pin和unpin当前tabalt+m
, 静音和解除静音当前tab
(待做)
XML
转JSON
,:wq
等价于:x
VIDEO 4 Data Wangling (TODO)
正则表达式通常以
/
开始和结束。正则表达式在线调试工具regex debugger.
除换行符之外的”任意单个字符”*
匹配前面字符零次或多次+
匹配前面字符一次或多次[abc]
匹配a
,b
和c
中任意一个, 在括号中使用^
即为非(RX1|RX2)
任何能够匹配RX1
或RX2
的结果^
行首$
行尾
sed
命令-E
参数支持对正则表达式的拓展
uniq
命令去除重复行-c
参数输出过滤后的行数
sort
命令按照数字顺序对输入进行排序(默认情况下是按照字序列排序)-r
参数进行倒序排序-n
参数表示仅排序到第n
个部分
awk
编辑器,awk
其实是一种编程语言具体可以查看man awk
和tldr awk
学习一下交互式正则表达式教程
VIDEO 6 Version Control(Git)
- Git中的对象可以是blob(数据对象)、Tree或Commit
- 所有的snapshot都可以用SHA-1哈希(40位的十六进制字符)来标记,但显然
Reference
更方便。 HEAD
引用可以通过两种方式查看,cat .git/HEAD
;git symbolic-ref HEAD
。- 基础
git help <command>
:获取git命令的帮助信息git init
:创建一个新的git仓库,其数据会存放在一个名为.git
的目录下git status
:显示当前仓库的状态git add <filename>
:添加文件到暂存区(staging Area)git commit
:创建一个新的提交; 如何编写良好的提交信息, 为什么要编写良好的提交信息git
的提交信息- 用空行将主体与主体分开
- 将主题行限制为50个字符
- 将主题行大写
- 不要以句点结束主题行
- 在主题行中使祈使句语句
- 将正文包裹在72个字符处
- 用正文来解释
what
why
vs.how
git log
:显示日志历史git log --all --graph --decorate
:可视化历史记录(有向无环图)git diff <filename>
:显示与暂存区文件的差异git diff <revision> <filename>
:显示某个文件两个版本之间的差异git checkout <revision>
:更新HEAD和目前的分支
- 分支和合并
git branch
:显示分支git branch <name>
:创建分支git checkout -b <name>
:创建分支并切换到该分支, 相当于git branch <name>; git checkout <name>
git merge <revision>
:合并到当前分支git mergetool
:使用工具来处理合并冲突git rebase <name>
:创建更线性的提交历史
- 远端操作
git remote
:列出远端git remote add <name> <url>
:添加一个远端git push <remote> <local branch>:<remote branch>
:将对象传送至远端并更新远端引用git branch --set-upstream-to=<remote>/<remote branch>
:创建本地和远端分支关联关系git fetch
:从远端获取对象git pull
:相当于git fetch; git merge
git clone <url> <name>
:从远端下载仓库并命名为name
- 撤销
git commit --amend
:编辑提交的内容或信息git reset HEAD <file>
:恢复暂存的文件- `git checkout –
:丢弃修改
- Git高级操作