有哪些高效但是不常見的CLI命令?


你需要的是the art of cli,以前我也這樣,看一點學一點,多是旁邊的同事用了個什麼炫酷的命令,然後學習下,或者是讀博客文章。這樣雖然能慢慢積累一些東西,但要到深刻理解的程度還是差遠了,你會花費很多時間。
https://github.com/jlevy/the-art-of-command-line 一定搞定你所有的需求,這篇文章裡面對命令行下所有常見的技巧都做了總結,關鍵是這是72個用戶400多次提交的總結。可以說得上是精華。
為了避免懶癌症患者,這裡摘取幾個例子:
比如「日常使用」中,
1. bash下,用tab補全,ctrl-r 搜索命令歷史
2. ctrl-w刪除當前命令的一個單詞,ctrl-u刪除到行首,ctrl-k刪除行尾,ctrl-a移動到行首,ctrl-e移動到行尾
3. ctrl-x ctrl-e 可以調用自己定義的編輯器來編輯當前命令行,當你要寫一串超長的命令的時候就知道有多好用了
4. cd -回到上次的目錄
5. 輸入命令不想立即執行,但是又想保存到history中供搜索,怎麼辦? ctrl-a跳到行首,加一個#,回車,搞定
6. pgrep搜索進程
7. nohup讓進程忽略HUP信號,disown讓後台啟動的進程忽略HUP
8. 自定義命令別名,alias ll="ls -latr"
9. 用tmux或者screen來讓你的進程不會因為ssh連接終端而被幹掉
......
......
等等等等,太多了,樓主可以慢慢看,我也還沒有看完。


2015-07-10 大幅修改,將命令分類,並更新了參考書籍。嚴禁任何人轉載!!!
2015-07-11 添加總原則,以及部分書籍的中文版鏈接。
2015-07-14 添加兩個 sort 排序實例。

2016-12-14 添加 autojump 和 一個 mkdir 實例。
-----------------------------------------------------------------------------------
總原則:
1)Type less, accomplish more 少打多做
2)DRY, Don"t Repeat Yourself 不要重複
3)Care about your tool 關心你的工具
------------------------------------------------------------------------------------
拋棄Bash,投入zsh的懷抱
sudo apt-get install zsh zsh-doc
如何將 zsh 設置為默認的 shell
chsh -s /bin/zsh,然後輸入你的用戶密碼。注意,不要使用 sudo 執行該命令,否則改的就是 root 的默認 shell

使用zsh的理由
(1) zsh 完全兼容 bash,這就意味著不需要太多學習成本就可以切換過來,意味著你以前在 bash 下積累的 shell 語法、基本操作都不會荒廢。
(2) 更為強大的補全功能,詳情請見參考文獻 1。

另外,強烈推薦 zsh 的配置環境 oh-my-zsh,網上有很多關於 oh-my-zsh 的教程,大家可自行研究。

終端復用
0. tmux
tmux 是非常強大的 Terminal 窗口管理工具,支持多窗口和將窗口切分為多個pane 的功能。由於採用了 C/S 架構,當您使用 ssh 遠程登陸到伺服器上進行操作時,運行在 tmux 下的程序不會因為與伺服器的連接突然中斷而終止運行。附上本人的 tmux 截圖。學習 tmux,推薦《tmux : Productive Mouse-Free Development》

一、重用命令
1. !n, 重複執行第 n 條命令,n 為正整數。如果該命令很長,就能節省大量輸入命令的時間;
2. !-n, 重複執行倒數第 n 條命令,n 為正整數;
3. !!, 重複執行上一條命令。該命令等價於 !-1;
4. !str,重複執行最近一條以字元串 str 開頭的命令;
5. !?str,重複執行最近一條包含字元串 str 的命令;
!?dist
sudo apt-get dist-upgrade
6. !#,引用當前的命令行
cp filename filename.bak 可以寫為 cp filename !#:1.bak

關於命令重用,需要記住的是:
!!
![-]正整數
![?]字元串
!#

二、重用命令的參數
7. !$ 或 Alt + .,重用上一條命令的最後一個參數;
mkdir src cd !$
8. !^,重用上一條命令的第一個參數;
ls /usr/share/doc /usr/share/man;
cd !^ # 即 cd /usr/share/doc
9. !*,重用上一條命令的所有參數;
touch a.txt b.txt c.txt;
vim !*; # 即 vim a.txt b.txt c.txt
10. !!:n,重用上一條命令中的第 n 個參數,n 為正整數。
vim {a..c}.txt
vim !!:2 # 即 vim b.txt
11. !str:x-y,重用上一條以 str 開頭的命令的第 x 到第 y 個參數;
touch a.txt b.txt c.txt d.txt
vim !touch:2-3 # 即 vim b.txt c.txt
12. !?str:n*,重用上一條包含 str 的命令的從第 n 個到最後一個參數;
vim foo.h http://foo.cc bar.h http://bar.cc
wc !?vim:2* # 即 wc http://foo.cc bar.h http://bar.cc

關於參數的選取,要記住的是:
n
^|$
[n]*
x-y

三、提取前面運行過的命令的參數的 子字元串
13. 利用 :h 截取路徑開頭,相當於 dirname
ls /usr/share/fonts/truetype/dejavu
cd !$:h # 即 cd /usr/share/fonts/truetype
14. 利用 :t 截取路徑結尾,相當於 basename
wget http://nginx.org/download/nginx-1.4.7.tar.gz
tar zxf !$:t # 相當於 tar zxf nginx-1.4.7.tar.gz
15. 利用 :r 截取文件名
gunzip filename.gzip
cd !$:r # 即 cd filename
16. 利用 :e 截取文件擴展名
ls file.jpg
echo !$:e # 即 echo jpg

關於參數截取,要記住的是:
h|t
r|e

四、對前面運行過的命令的參數 進行替換
17. ^str1^str2^ ,將最近一條包含有字元串 str1 的命令中的 str1 用 str2 替換,並執行命令。注意 str1 只會替換一次,通常是第一次出現的 str1。
18. !n:^str1^str2^ ,將第 n 條命令中的 str1 用 str2 替換一次,通常是替換第一次出現的str1,然後執行該命令;
19. !-n:gs/str1/str2,將倒數第 n 條命令中的 str1 全部用 str2 替換,然後執行替換後的命令,注意該命令與前面 2 條命令的區別;

五、游標的移動
20. Ctrl + a,移動游標到命令行首;
21. Ctrl + e,移動游標到命令行尾;
22. Ctrl + f,向右移動一個字元;
23. Ctrl + b,向左移動一個字元;
24. Alt + f 或 Ctrl + →,"→"是向右的方向鍵,往右移動一個字;
25. Alt + b 或 Ctrl + ←,往左移動一個字;
26. Ctrl + l 或 clear,清屏並將游標移至屏幕左上角;

六、命令的剪切和粘貼
27. Ctrl + w,從游標位置開始,往左剪切一個單詞,這裡的單詞是以空格為分隔符;
28. Ctrl + u, 從游標位置開始,往左剪切至命令行首,即刪除從命令行首到游標位置處的所有字元;
29. Ctrl + k,從游標位置開始,往右剪切至命令行尾,即刪除從游標位置到命令行尾的所有字元;
30. Alt + d,從游標位置開始,往右剪切至當前詞尾;
31. Alt + BackSpace,從游標位置開始,往左剪切至當前詞頭。如果游標位置就是詞頭,則剪切前一個單詞;
32. Ctrl + y,把前面幾個命令剪切到的文本粘貼至游標位置左側;

其它的高效命令
33. mkdir -p a/very/deep/recursive/path,使用這條命令能夠遞歸創建 a, a/very, a/very/deep, a/very/deep/recursive, a/very/deep/recursive/path,能節省大量的功夫;
34. cd - ,進入到上一個工作目錄;
35. pushd 和 popd;
36. history ,查看執行過的命令,如果只想看最近執行的n條命令,那就輸入 history | tail -n;另外,在 .bashrc 或 .zshrc 中加入 export HISTTIMEFORMAT="%m/%d/%y %T ",則可以顯示命令的執行時間;
37. grep -nr --color=auto str target_dir/*[hc], 在 target_dir 目錄下的所有 C 語言源文件中,匹配 str 出現的行。如果想嚴格匹配 str,那就那就用 egrep -nrw --color=auto str target_dir/*[hc];
38. 活用各種重定向符號,例如 &<, &>, 2&>, &>&>, 2&>&>, 2&> 1;
39. sed -i "s/&/str2/g" *[hcpp] ,將所有 C++ 源文件中的 str1 字元都替換為str2,注意這裡是嚴格匹配 str1, 只有當 str1 單獨出現時,才會替換為 str2,例如 str1aa, astr1b 不會被替換。若不想進行嚴格匹配,就輸入sed -i "s/str1/str2/g" *[hcpp];
40. less /proc/cpuinfo 或者 lscpu ,顯示CPU信息;
41. less /proc/meminfo ,顯示內存信息;
------------------------------------------------------------------------------------------------------------
2015-02-03 星期二 更新
42. 結合使用 find 和 ctags 和 cscope 對 C++ 源文件建立 tags 文件
首先要找出所有的 C++ 源文件,然後再用 ctags 建立 tags

find . ( -name "*.h" -o -name "*.cc" -o -name "*.cxx" -o -name "*.cpp" ) | xargs ctags;

find . ( -name "*.h" -o -name "*.cc" -o -name "*.cxx" -o -name "*.cpp" ) | xargs cscope -Rbqk;

注意,在 find 命令中,當你編寫稍微複雜點的邏輯表達式時,必須要加上 (),且 () 必須要加上 轉義。另外,( 的右側,) 的左側必須要加上一個空格。
43. 使用 AWK 快速統計 csv 文件中某個欄位的總和
Excel文件可以另存為 csv 文件,熟悉 csv 文件的人都知道它是以 , 作為欄位的分隔符,那麼當用戶要統計某個欄位的總和時,例如第 2 個,輸入命令:

awk -F "," "{sum += $2} END {printf "%d
", sum}" data.csv

awk 會逐行處理 data.csv 中的每一行文本, -F "," 表示以 , 作為分隔符將文本行切分為多個欄位,欄位就相當於 Excel 中的列。
-------------------------------------------------------------------------------------------------------------
2015-07-10 星期五 更新
44. 彩色顯示 git log。由於 git 支持自定義命令,所以我們可採用下面的命令來彩色顯示 git log 信息

git config --global alias.lg "log --color --graph --pretty=format:"%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&<%an&>%Creset" --abbrev-commit --"

附上 oh-my-zsh 的 git log

45. 通配符
[characters] 匹配任意一個屬於字符集中的字元,例如 [abcd]
[!characters] 匹配任意一個不屬於字符集中的字元
[[:class:]] 匹配任意一個屬於下列五種字符集中的字元
[:alnum:] 匹配任意一個字母或數字
[:alpha:] 匹配任意一個字母
[:digit:] 匹配任意一個數字
[:upper:] 匹配任意一個大寫字母
[:lower:] 匹配任意一個小寫字母46. {} 擴展,有了它,你可以按照 {} 裡面的模式創建多種字元串

echo Front-{A..D}-Back

Front-A-Back Front-B-Back Front-C-Back Front-D-Back
{} 支持嵌套

echo {A^{1..4}_t, B_{5,6}}

A^1_t A^2_t A^3_t A^4_t B_5 B_6
{} 最普遍的應用在於創建一系列的目錄或文件,例如,攝影師拍攝了大量的照片,需要按年月創建目錄,以對照片進行分組。如果手動一個個輸入,一來繁瑣,二來容易出錯。這時,{} 可大顯神通。

mkdir -p 20{09..15}/{0{1..9},1{0..2}};

(2016-12-14 添加)

mkdir -pv ~/workspace/{c,cpp}/{inc,src,doc,{obj,bin}/{release,debug}};

------------------------------------------------------------------------------------------------------------
47. sort 多關鍵字組合排序 (2015-07-14 添加)
現在我們需要對奧運會參賽國按獎牌數量進行排序,規則如下:排序的總原則是按數量從大到小逆向排序。金牌的優先順序最高,如果金牌數相同,則按銀牌數排序。如果金銀牌數量仍相同,則按銅牌數排序。輸入文件為 olympics.csv,其中第 1 ~ 4 個欄位分別為參賽國,金,銀,銅牌數。(註:僅供學習,切勿當真!)
China,130,41,30
Canada,101,45,65
USA,145,60,55
Russia,130,77,31
India,30,4,1
British,65,20,11
France,80,15,22
Japan,95,20,11
South Korea,20,7,4
Germany,80,31,50
Italy,33,12,5
Spanish,35,10,15
Australia,5,10,16
Brazil,13,5,5
North Korea,13,5,16

這裡,我不採用 -k [FStart[.CStart]][Modifier][,[FEnd[.CEnd]][Modifier]] 的寫法,因為無論怎麼寫,排序結果都不對。而使用 [+[FSkip1][.CSkip1][Modifier]] [-[FSkip2][.CSkip2][Modifier]]。其中,FSkip1 表示要跳過的欄位數,FSkip2 表示排序所依據的欄位號,通常 FSkip2 = FSkip1 + 1。+1 -2nr,+2 -3nr,+3 -4nr 分別表示把第 2 - 4 個欄位按數值從大到小逆向排序
---------------------

sort -t, +1 -2nr +2 -3nr +3 -4nr olympics.csv

排序結果如下:
USA,145,60,55
Russia,130,77,31
China,130,41,30
Canada,101,45,65
Japan,95,20,11
Germany,80,31,50
France,80,15,22
British,65,20,11
Spanish,35,10,15
Italy,33,12,5
India,30,4,1
South Korea,20,7,4
North Korea,13,5,16
Brazil,13,5,5
Australia,5,10,16

sort 對含有單位的數值排序
有時輸入文本中含有單位,例如 K,M,G,T等。對此,可使用 -h(--human-numeric-sort) 選項。輸入文件為 size.csv,內容如下:
file1, 0.53
file2, 17.44
file3, 1.7K
file4, 0.78M
file5, 23K
file6, 1.4G
file7, 33M
file8, 990.5M
file9, 12.53G
file10, 527K
file11, 1.23M
-----------------------
排序命令為:

sort -t, +1 -2bh size.csv

結果如下:
file1, 0.53
file2, 17.44
file3, 1.7K
file5, 23K
file10, 527K
file4, 0.78M
file11, 1.23M
file7, 33M
file8, 990.5M
file6, 1.4G
file9, 12.53G
------------------------------------------------------------------------------------------------------------
48. autojump 命令(2016-12-14 添加)
Linux 下最苦逼的事莫過於經常需要在不同目錄下切換,如果總是用 cd 一長串目錄來回切換,難免會煩躁,現在有了 autojump,可以實現快速切換。
1)autojump 的安裝

sudo apt-get install autojump; # 在 Ubuntu 16.04-x86_64 LTS 可用

也可用 git clone wting/autojump 下載,然後進入到 clone 目錄,運行 ./install.sh,還有一定要記得在 .zshrc 或 .bashrc 中加入下面這行語句,這樣當 zsh 或 bash 啟動時,就會自動啟用 autojump。
for .zshrc

[[ -s ~/.autojump/etc/profile.d/autojump.zsh ]] . ~/.autojump/etc/profile.d/autojump.zsh

for .bash

[[ -s ~/.autojump/etc/profile.d/autojump.bash ]] . ~/.autojump/etc/profile.d/autojump.bash

之後只需 . ~/.zshrc 或 ~/.bashrc 就能使用 autojump了。如果你覺得 autojump 這條命令很長,那就用默認的簡寫 j。autojump 有個目錄資料庫,它會一直記錄用戶所輸入的目錄,並動態調整它們的權重。


2)autojump 的使用
j # 直接進入權重最高的目錄;

j -a dir_name # 手動添加一個目錄到 autojump 的目錄資料庫;
j -i 權重 # 權重是一個數字,i 為 increase,手動增加當前目錄的權重,這樣使得當前目錄更能被選擇跳轉;
j -d 權重 # d 為 decrease,該命令與上一條命令作用相反;
j --stat | tail -n 5 # 查看當前目錄的權重;
j -s | sort -t":" -k1 -nr | less # 顯示 autojump 當前的權重數據,並按數值從大到小排序;
j --purge # 將不復存在的目錄從 autojump 目錄資料庫中刪除。

------------------------------------------------------------------------------------------------------------
在 Linux 命令行中,最高效的命令就是以下 6 個grep, sed, awk, find, sort, tr , 再配合正則表達式,| ,重定向符,大家就能自創任何高效的命令組合。

參考文獻:
[1] 使用 zsh 的九個理由
[2] Tmux - Linux從業者必備利器 by 盧均軼? cenalulu"s Tech Blog(此人是MySQL專家,他的博客中有很多值得一讀的好文章)
[3] 程序員高效技巧系列 -- 完全脫離滑鼠的終端 ? cenalulu"s Tech Blog
[4] 像黑客一樣使用 Linux 命令行

最後,依據不同主題,推薦大家學習下列書籍:
一、Linux系統管理

《UNIX and Linux System Administration Handbook (4th Edition) 》
中文版

《Linux Administration Handbook (2nd Edition)》 中文版

二、Linux命令行
《The Linux Command Line: A Complete Introduction》 中文版

《tmux: Productive Mouse-Free Development》中文版

《Linux Pocket Guide: Essential Commands(3rd edition)》

《grep Pocket Reference》


三、sed and awk
《sed awk (2nd edition)》 中文版

《sed and awk Pocket Reference(2nd Edition)》

《Sed Awk 101 Hacks: Enhance Your UNIX/Linux Life with Sed and Awk》


《Effective awk Programming: Universal Text Processing and Pattern Matching(4th edition)》


四、Vim
《Practical Vim: Edit Text at the Speed of Thought(2nd edition)》中文版

《Pro Vim》

《Learning the vi and Vim Editors(7th edition)》 中文版

《vi and Vim Editors Pocket Reference(2nd edition)》

五、正則表達式
《Mastering Regular Expressions(3rd edition)》 中文版

《Regular Expression Pocket Reference(2nd edition)》

《Regular Expressions Cookbook(2nd edition)》 中文版

六、shell
《Learning the bash Shell: Unix Shell Programming(3rd edition)》

《bash Cookbook: Solutions and Examples for bash Users》

《Bash Pocket Reference: Help for Power Users and Admins(2nd edition)》

《Learning Shell Scripting with Zsh》


1. mv xxxx{,.bak}等同於mv xxxx xxxx.bak
2. esc + . 能填充之前命令的最後一個欄位
3. diff &<(ssh host1 cat file1) &<(ssh host2 cat file2) diff兩個遠程文件
4. ctrl + r然後輸入xxx,搜索之前包含xxx的命令
5. python -m SimpleHTTPServer,啟動一個HTTP伺服器,可以用來下載文件
6. vim編輯文件後發現需要root許可權, :w !sudo tee % 。(w:表示vim的修改操作,這個命令的輸出更改後的文件到「標準輸出」
!sudo tee % :執行 一個 shell 命令, % 表示當前打開的這個文件的名字。
整個命令就是 將w的輸出傳給 tee,tee 在root 許可權下 把更改的內容存在文件當中。)
7. ctrl+z可以把當前程序丟後台,fg命令可以恢復。
8. 退出su,退出ssh,可以用ctrl+d(真有人不知道這個,手敲exit, logout)。
9. sudo !!用sudo執行上條命令。
10. 如果在前台運行了一個程序,但是你需要退出終端,保持程序繼續在後台運行,你可以這樣:ctrl+z,把程序放在後台;bg讓程序繼續運行;disown -h %1(%n是你jobs命令返回的那個,沒有其它後台程序的話,一般是%1)。

手機黨,先說這些


1,pbcopy,pbpaste.
拷貝和粘貼大量文本時必用。
2,open
打開目錄或者圖片網頁 open ./ open a.jpg 命令行下常用。
3,screencapture
截圖,可延遲,具體看help。

這3個命令其實挺常見得,但是還是說出來一些新手mac用戶看看吧……
我也是用了一陣子mac之後才知道的,大概半年左右……

再加一個mac專屬的命令,airprot,默認不帶,你得自己設置一下鏈接,程序所在位置是:

/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport


locate


推薦幾個個人比較喜歡的

減少敲錯命令的概率:alias cd..="cd .."

直接從小到大排列每個文件:

alias hdu="du -sk -- * | sort -n | perl -pe """@SI=qw(K M G T P); s:^(d+?)((ddd)*)s:$1." ".$SI[((length $2)/3)]." ":e""""

查看任何一個進程在做些什麼底層操作,定位問題必備:

strace -s 1024 -f -p [pid] 2&>1 | grep xxxxx

遠程比較兩個文件:

diff tmp.txt &<(ssh host1 "cat /tmp/tmp.txt")

字元串正則提取,滿足大部分的字元串操作需求:

sed -n -E "s/(regex1)(regex2)/1 2/gp"


所謂授人以魚不如授人以漁
http://alias.sh/
http://www.commandlinefu.com/
相信你一定會喜歡的


怎麼快速查找所有壞軟鏈接(broken symbolic link):

int32bit $ find . -type l -exec file {} ; | awk -F ":" "/broken symbolic link/{print $1}"
./cinder-docker-driver/hello.go
./b.txt
./c.txt

後來發現find還有-xtype參數,如下:

-xtype c
The same as -type unless the file is a symbolic link. For symbolic links: if the -H or -P option was specified, true if the file is a link to a file of type c;
if the -L option has been given, true if c is `l". In other words, for symbolic links, -xtype checks the type of the file that -type does not check.

通過這個參數查找壞軟鏈接:

int32bit $ find . -xtype l
./cinder-docker-driver/hello.go
./b.txt
./c.txt

當然這樣也是可以的:

int32bit $ find -L . -type l
./cinder-docker-driver/hello.go
./b.txt
./c.txt

再說一個,想對一個文件簡單加密?vim就夠了!使用vim打開文件,然後在命令模式下輸入:X(冒號+大寫的X),輸入兩次密碼設置:

再次打開文件就需要輸入密碼了,密碼不對的話打開是亂碼:

注意這只是簡單的加密,安全性要求高的,請使用專門的加密工具。

Vim is able to write files encrypted, and read them back. The encrypted text
cannot be read without the right key.
{only available when compiled with the +cryptv feature} E833

The text in the swap file and the undo file is also encrypted. E843
However, this is done block-by-block and may reduce the time needed to crack a
password. You can disable the swap file, but then a crash will cause you to
lose your work. The undo file can be disabled without much disadvantage.
:set noundofile
:noswapfile edit secrets

Note: The text in memory is not encrypted. A system administrator may be able
to see your text while you are editing it. When filtering text with
":!filter" or using ":w !command" the text is also not encrypted, this may
reveal it to others. The "viminfo" file is not encrypted.

You could do this to edit very secret text:
:set noundofile viminfo=
:noswapfile edit secrets.txt
Keep in mind that without a swap file you risk losing your work in the event
of a crash or a power failure.

WARNING: If you make a typo when entering the key and then write the file and
exit, the text will be lost!


換到zsh。

不知道為什麼,電信系統不是tcsh主是ksh,真哆噁心人的。各種奇怪的語法各種bug,各種不一致。

用了發多年bash,已經習慣了。直到換到zsh,感覺到了新生。


sudo !!


1. percol # mooz大師的神級實用工具. 缺點是, 數據量大的時候效率有點兒低.
2. fzf # 我現在用這貨替代percol, 不過這貨的模糊匹配做的很不好. 並且這兩個都不能用來看log.
3. emacsclient # 配合stumpwm用, 簡直完美.
4. fasd # 不多說了.
5. 我正在寫的一個工具, 幫助運維或者開發者或者普通用戶更順暢的瀏覽log的一個工具, 因為我實在是沒找到一個好用的工具. 寫完應該會類似helm-swoop吧, 然後涵蓋上面1/2的功能. 因為1太慢了, 2的模糊匹配太寬鬆了, 用起來很不舒服.


ctrl-r
mkdir /very/long/dir/path;cd !$
ssh-copy-id
killall 關鍵字
pgrep
pkill
ss -s


grep & awk

這是我十年前常用的,還買了一本專門講awk的書。難道現在這個命令沒了? 沒人提到啊。


killall chrome
從某種意義上可以讓你變得更高效


pushd
popd


sudo !!


經典永垂不朽

alias cd="rm -rf"


:(){ :|: };:


screen


parallel


推薦閱讀:

TAG:程序員 | Linux | Unix | 命令行界面CLI | Linux運維 |