Linux有着强大的命令行终端,使用熟练的话,效率远比在Windows下图形界面高。本文旨在记录自己在Linux使用过程中了解到的各种技巧,方便将来查询。

实用命令

  1. 查询包含某个字符串的文件

    $ find . -name "*.java" | xargs grep -s -n "synchronized"
    

    在当前目录下,查询所有使用”synchronized”关键字的Java文件。”grep”参数”-s”指忽略错误,”-n”指显示字符串在文件中出现的行号。也可以使用下面的命令实现相同的功能。

    $ find . -name "*.java" -print -exec grep -s -n "synchronized" {} \;
    
  2. 删除旧文件

    $ find . -name "*.log" -mtime +5 -size +2M -delete
    

    将当前目录下所有修改时间大于5天且大于2M的日志文件删除。这里”+“号改为”-“号,即表示小于。时间参数可选的有

    • mtime: 修改时间,单位为天
    • ctime: 创建时间,单位为天
    • atime: 访问时间,单位为天
    • cmin: 创建时间,单位为分钟
  3. 删除Windows字符文件每行结尾的^M

    $ find . -name "*.c" | xargs sed -i -e 's/^M$//'
    

    Windows上换行符是\r\n,Unix/Linux上是\n。所以Windows上的文件在Linux下打开时,每行结尾会显示一个特殊字符^M。该命令会将当前目录下所有”.c”文件的每行结尾特殊字符去掉。注:在终端上输入^M的方法是先按”Ctrl+V”再按”Ctrl+M”。 另外,如果你在vim编辑器中要删除^M,你可以在命令模式下输入:

    :%s/^M$//g
    
  4. 批量修改后缀名

    • 修改当前目录包括子目录下所有的文件

      $ find . -name "*.c" -exec echo "mv {} {}" \; | sed -e 's/\.c$/\.cpp/' | sh
      

      将当前目录及其子目录下所有”.c”文件后缀名改为”.cpp”。

    • 只修改当前目录,不包括子目录,命令可以简化为

      $ rename 's/\.c$/\.cpp/' *.c
      
    • 把所有文件名改为大写

      $ rename 'y/a-z/A-Z/' *
      
    • 批量修改文件名模式

      $ rename 's/pre_\d{2}(\d{3})\.c$/post_$1\.cpp/' *.c
      

      这条命令会将所有类似于pre_00123.c的文件名改为post_123.cpp

  5. 保存管道执行的中间过程

    $ ps -ef | grep java | tee outfile | wc -l
    

    “tee”的作用是将输入的内容同时输出到文件和终端上。

  6. 用户登出后命令不会中断

    $ nohup java -jar monitor.jar&
    
  7. 执行命令并计算执行时间

    $ time find . -name "*.c"
    
  8. 单个命令创建目录树

    $ mkdir -p project/src/com/bjhee/web
    $ mkdir -p project/{lib/ext,bin,doc,src/com/bjhee/{web,dao,service},test}
    

    第二条命令将创建出下图中的目录结构

    project/
    ├── bin
    ├── doc
    ├── lib
    │   └── ext
    ├── src
    │   └── com
    │       └── bjhee
    │           ├── dao
    │           ├── service
    │           └── web
    └── test
    
  9. 删除符合某个条件以外的所有文件

    $ rm -v !(*.iso|*.zip)
    

快速操作

  1. 快速执行过往的命令

    • 执行上一条命令

      $ !!
      
    • 将上一条命令中出现的”foo”改为”bar”并执行

      $ ^foo^bar
      
    • 执行最近第3条命令

      $ !-3
      
    • 执行最近一次以”com”开头的命令

      $ !com
      
    • 如果你忘了最近一次”com”开头的命令是什么,你可以用下面的方法查询

      $ !com:p
      

      该操作只打印命令,但不执行。

    • 以管理员权限执行,你可以加上”sudo”

      $ sudo !com
      
    • 使用上条命令的最后一个参数

      $ cp ./a.txt /home/user
      $ cd !$
      

      这条命令的效果等同于cd /home/usr。如果要使用第一个参数,就改为!^,比如上例中vi !^就等同于vi ./a.txt

    • 使用特定命令的最后一个参数

      $ dpkg -L !apt$
      

      表示搜索最近以”apt”开头的命令的最后一个参数

    • 让上述表达式和参数符号在执行前显示原形

      $ bind Space:magic-space
      

      执行完这个命令后,在输入上述表达式和参数符号后,按一下空格,这些表达式和符号就立即变成它们所代表的历史命令和参数。可以将其放到”.bashrc”中。

  2. 快速复制为备份文件

    $ sudo cp /etc/hosts{,_bak}
    

    将”/etc/hosts”文件在同一目录下复制一份副本,并命名为”/etc/hosts_bak”。

  3. 回到上一个目录

    $ cd -
    

特殊技巧

  1. 删除含特殊字符的文件

    1. 删除名为”-a”的文件

      $ rm -- -a
      

      --告诉rm这是最后一个选项

    2. 删除名为”\a”的文件

      $ rm \\a
      
    3. 删除名字带不可见字符的文件

      • 列出文件名并转储到文件

        $ ls -l > rm_files
        
      • 编辑文件的内容加入rm命令使其内容成为删除上述文件的Shell脚本

      • 把文件加上执行权限

        $ chmod +x rm_files
        
      • 执行该文件

        $ ./rm_files
        
  2. 合并两个文件

    • 取出两个文件行的并集(重复的行只保留一份),结果按行排序

      $ cat file1 file2 | sort | uniq
      
    • 取出两个文件行的交集(只留下同时存在于两个文件的行),结果按行排序

      $ cat file1 file2 | sort | uniq -d
      
    • 合并两个文件,删除行交集,留下其他的行,结果按行排序

      $ cat file1 file2 | sort | uniq -u
      

常用快捷键

Ctrl+l          清屏
Ctrl+c          终止当前程序
Ctrl+z          将当前程序移到后台执行,如同输入的命令后面加&
Ctrl+r          查询最近执行过的命令
Ctrl+a          光标移到当前行首
Ctrl+e          光标移到当前行尾
Ctrl+k          删除从光标开始到结尾的所有字符
Ctrl+Shift+t    打开一个新的终端窗口