高效使用Linux 命令行

使用 ^ 删掉多余的部分

1
2
3
grep fooo ~/.zlua
^o
grep foo ~/.zlua     # ^o 之后的执行语句

使用 ^old^new 完成替换

1
2
3
4
5
6
7
touch test.txt
echo "abc cba aaa bbb" > test.txt
cat tets.txt
cat: tets.txt: No such file or directory
^ts^st
cat test.txt
abc cba aaa bbb

上面的例子中:

  1. 先新建一个可以cat 的测试文件并输入一些内容
  2. 故意cat 错文件名
  3. 使用 ^xxx^yyy 来实现命令行上替换错误的文件名

使用 !:gs/old/new 将old 全部替换成 new

1
2
3
4
5
6
7
8
9
[user@Linux92 cmd_test]$ touch test2.txt
[user@Linux92 cmd_test]$ echo "echo test2.txt end" > test2.txt
[user@Linux92 cmd_test]$ cat test2.txt
echo test2.txt end
[user@Linux92 cmd_test]$ cat test.tx
cat: test.tx: No such file or directory
[user@Linux92 cmd_test]$ !:gs/test.tx/test2.txt
cat test2.txt
echo test2.txt end

Terminal搜索历史命令

Ctrl + r 逆向搜索历史命令

Ctrl + n/p 下一条/上一条历史命令

强大的 ! 的使用

执行上一条命令

1
2
!!
sudo !!

执行以foo关键字开头的命令

1
2
3
4
5
6
7
8
9
[user@Linux92 cmd_test]$ history | grep abc
 1013  echo "abc cba aaa bbb" > test.txt
 1015  echo "abc cba aaa bbb" >> test.txt
 1029  history | grep abc
[user@Linux92 cmd_test]$ !his
history | grep abc
 1013  echo "abc cba aaa bbb" > test.txt
 1015  echo "abc cba aaa bbb" >> test.txt
 1029  history | grep abc

执行包含foo 关键字的命令

1
2
[user@Linux92 cmd_test]$ !?abc
echo "abc cba aaa bbb" >> test.txt

!# 引用当前行

1
2
3
[user@Linux92 cmd_test]$ cp test.txt  test.txt.old
[user@Linux92 cmd_test]$ cp test.txt !#:1.oldd
cp test.txt test.txt.oldd

其中:

!#:0 即cp

!#:1 即test.txt

!$ 得到上一条命令的最后一个参数

1
2
3
[user@Linux92 cmd_test]$ mkdir videos
[user@Linux92 cmd_test]$ cd !$
cd videos

!$ 得到上一条命令的第一个参数

1
2
3
4
5
6
7
[user@Linux92 videos]$ ls ../ ../videos/
../:
cp.old  test2.txt  test.txt  test.txt.old  test.txt.oldd  videos

../videos/:
[user@Linux92 videos]$ cd !^
cd ../

:@ 注意 : 第0个参数是ls 第1 个参数是 ../

!:n 得到上一条命令的第n 个参数

1
2
3
[user@Linux92 cmd_test]$ touch 1.txt 2.txt 3.txt
[user@Linux92 cmd_test]$ vim !:2
vim 2.txt

通过 !:x-y 得到上一条命令从 x 到 y 的参数

1
2
3
4
[user@Linux92 cmd_test]$ touch 1.txt 2.txt 3.txt
[user@Linux92 cmd_test]$ vim !:1-2
vim 1.txt 2.txt
2 files to edit

通过!:n* 得到上一条命令从n 到最后的参数

1
2
3
4
[user@Linux92 cmd_test]$ touch 1.txt 2.txt 3.txt
[user@Linux92 cmd_test]$ vim !:1*
vim 1.txt 2.txt 3.txt
3 files to edit

通过 !* 得到上一条命令所有的参数

1
2
3
4
[user@Linux92 cmd_test]$ touch 1.txt 2.txt 3.txt
[user@Linux92 cmd_test]$ echo !*
echo 1.txt 2.txt 3.txt
1.txt 2.txt 3.txt

修饰符

利用 :h 选取目录路径

1
2
3
4
5
6
[user@Linux92 cmd_test]$ touch videos/a
[user@Linux92 cmd_test]$ ls ~/cmd_test/videos/a
/home/user/cmd_test/videos/a
[user@Linux92 cmd_test]$ echo !$:h
echo ~/cmd_test/videos
/home/user/cmd_test/videos

相当于 direname

利用 :t 选取文件路径

1
2
3
4
5
[user@Linux92 cmd_test]$ ls ~/cmd_test/videos/a.txt
/home/user/cmd_test/videos/a.txt
[user@Linux92 cmd_test]$ echo !$:t
echo a.txt
a.txt

相当于 basename

利用 :r 选取文件名

1
2
3
unzip filename.zip
cd !$:r
cd filename

利用 :e 选取扩展名

1
2
3
4
5
[user@Linux92 cmd_test]$ echo abc.jpg
abc.jpg
[user@Linux92 cmd_test]$ echo !$:e
echo .jpg
.jpg

利用:p 打印命令行

1
2
3
4
[user@Linux92 cmd_test]$ echo *
1.txt 2.txt 3.txt cp.old test2.txt test.txt test.txt.old test.txt.oldd videos
[user@Linux92 cmd_test]$ !:p
echo *

利用 :s 做替换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[user@Linux92 cmd_test]$ echo this that
this that
[user@Linux92 cmd_test]$ !:s/is/e
echo the that
the that
[user@Linux92 cmd_test]$ echo this that
this that
[user@Linux92 cmd_test]$ ^is^e
echo the that
the that

惯用法是 ^old^new

利用 :g 做替换全局操作

使用 !:gs/old/new 将old 全部替换成 new

利用 :u 将其更改为大写

仅 zsh 有

利用 :l 将其更改为小写

仅 zsh 有

定义后缀别名

仅 zsh 支持

使用 {} 构造字符串

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[user@Linux92 cmd_test]$ echo cp file.c{,.bak}
cp file.c file.c.bak
[user@Linux92 cmd_test]$ echo cp file.c{.tmp,.bak}
cp file.c.tmp file.c.bak
[user@Linux92 cmd_test]$ echo {a,b,c}.txt
a.txt b.txt c.txt
[user@Linux92 cmd_test]$ echo {,b,c}.txt
.txt b.txt c.txt
[user@Linux92 cmd_test]$ echo [abc].txt
[abc].txt
[user@Linux92 cmd_test]$ echo {a..c}.txt
a.txt b.txt c.txt
[user@Linux92 cmd_test]$ echo {a-c}.txt
{a-c}.txt
[user@Linux92 cmd_test]$ echo {01..5}.txt
01.txt 02.txt 03.txt 04.txt 05.txt
[user@Linux92 cmd_test]$ echo {1..10..2}.txt
1.txt 3.txt 5.txt 7.txt 9.txt
[user@Linux92 cmd_test]$ echo {1..10..-2}.txt
9.txt 7.txt 5.txt 3.txt 1.txt
[user@Linux92 cmd_test]$ echo {9..1..-2}.txt
9.txt 7.txt 5.txt 3.txt 1.txt
[user@Linux92 cmd_test]$ echo {01..3}/{baby,photo}
01/baby 01/photo 02/baby 02/photo 03/baby 03/photo
[user@Linux92 cmd_test]$ echo {{A..Z}, {a..z}, {0-9}}
{A, {B, {C, {D, {E, {F, {G, {H, {I, {J, {K, {L, {M, {N, {O, {P, {Q, {R, {S, {T, {U, {V, {W, {X, {Y, {Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, {0-9}}

{} 内的字符串以逗号隔开, 逐个与括号外的字符串拼接成新字符串

使用 `` 或 $() 做命令替换

1
2
3
[user@Linux92 cmd_test]$ vim `grep -l . *.oldd`
或者
[user@Linux92 cmd_test]$ vim $(grep -l . *.oldd)

以上命令实现了用vim 打开 grep -l . *.oldd 返回的结果

使用变量保存信息

1
2
LOG=/var/log/err.log
head $LOG

使用for…in 重复执行命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[user@Linux92 cmd_test]$ ll
total 20
-rw-rw-r--. 1 user user  0 May 23 23:05 1.txt
-rw-rw-r--. 1 user user  0 May 23 23:05 2.txt
-rw-rw-r--. 1 user user  0 May 23 23:05 3.txt
-rw-rw-r--. 1 user user 64 May 23 22:25 cp.old
-rw-rw-r--. 1 user user 19 May 23 22:07 test2.txt
-rw-rw-r--. 1 user user 64 May 23 22:21 test.txt
-rw-rw-r--. 1 user user 64 May 23 22:22 test.txt.old
-rw-rw-r--. 1 user user 64 May 23 22:23 test.txt.oldd
drwxrwxr-x. 2 user user 15 May 23 23:09 videos
[user@Linux92 cmd_test]$ for f in *.txt
> do
> echo $f
> mv $f $f.log
> done
1.txt
2.txt
3.txt
test2.txt
test.txt
[user@Linux92 cmd_test]$ ll
total 20
-rw-rw-r--. 1 user user  0 May 23 23:05 1.txt.log
-rw-rw-r--. 1 user user  0 May 23 23:05 2.txt.log
-rw-rw-r--. 1 user user  0 May 23 23:05 3.txt.log
-rw-rw-r--. 1 user user 64 May 23 22:25 cp.old
-rw-rw-r--. 1 user user 19 May 23 22:07 test2.txt.log
-rw-rw-r--. 1 user user 64 May 23 22:21 test.txt.log
-rw-rw-r--. 1 user user 64 May 23 22:22 test.txt.old
-rw-rw-r--. 1 user user 64 May 23 22:23 test.txt.oldd
drwxrwxr-x. 2 user user 15 May 23 23:09 videos
[user@Linux92 cmd_test]$ for f in *.log; do mv $f $f.log; done
[user@Linux92 cmd_test]$ ll
total 20
-rw-rw-r--. 1 user user  0 May 23 23:05 1.txt.log.log
-rw-rw-r--. 1 user user  0 May 23 23:05 2.txt.log.log
-rw-rw-r--. 1 user user  0 May 23 23:05 3.txt.log.log
-rw-rw-r--. 1 user user 64 May 23 22:25 cp.old
-rw-rw-r--. 1 user user 19 May 23 22:07 test2.txt.log.log
-rw-rw-r--. 1 user user 64 May 23 22:21 test.txt.log.log
-rw-rw-r--. 1 user user 64 May 23 22:22 test.txt.old
-rw-rw-r--. 1 user user 64 May 23 22:23 test.txt.oldd
drwxrwxr-x. 2 user user 15 May 23 23:09 videos

或者者一行搞定

1
for f in *.log; do mv $f $f.log; done

参考文章

https://talk.linuxtoy.org/