提高Linux工作效率的十大bash技巧

jopen 9年前發布 | 19K 次閱讀 Linux Bash

我喜歡鉆研bash環境。很多時候,在使用bash編程中,有些問題一遍又一遍的重復遇到。每次我都需要重新思考這些問題的解決方法。直到有一天我無法忍受,于是坐下來,編寫一個通用的函數,放入我的.bashrc文件中,部署到電腦上。

希望我的這些追求最大化命令行效率的努力成果也能給其他喜歡使用bash的朋友們帶來一些幫助。我更大的期望是我的這種行為能引起其他朋友的互動——給我提建議、提出更好的bash技巧,請在文后留言討論,或在 @程序師視野 給我留言。

別的不多說了,下面就是我的總結。

技巧一、用命令行往文件的頂部添加文字

每次我都會重新尋找這個命令的寫法。下面就是如何使用sed往一個文件頂部添加一行的方法:

sed -i '1s/^/line to insert\n/' path/to/file/you/want/to/change.txt

技巧二、用命令行往配置文件里插入多行文本

這種方法非常簡單,很多人都知道,下面就是如何用命令行將(>>)多行文本插入一個文件中。這里使用的是“here document”語法,它能讓你通過塊文本符號來將段落插入文件中,通常用的符合是EOF(意思是 “End Of File”):

cat >> path/to/file/to/append-to.txt << "EOF"
export PATH=$HOME/jdk1.8.0_31/bin:$PATH
export JAVA_HOME=$HOME/jdk1.8.0_31/
EOF

兩個”EOF“之間的所有內容都會被添加到文件中。

技巧三、用命令行遞歸方式全局搜索目錄文件和替換

如果你使用Eclipse,ItelliJ或其它IDE,這些工具的強大重構能力也許會讓你輕松實現很多事情。但我估計很多時候你的開發環境中沒有這樣的集成工具。

如何使用命令行對一個目錄進行遞歸搜索和替換?別想Perl語言,你可以使用find and sed。感謝Stack Overflow提供的指導:

# OSX version
find . -type f -name '*.txt' -exec sed -i '' s/this/that/g {} +

使用了一段時間后,我總結寫出了一個函數,添加入了 .bashrc ,就像下面這樣:

function sr {
    find . -type f -exec sed -i '' s/$1/$2/g {} +
}

你可以像這樣使用它:

sr wrong_word correct_word

技巧四、用命令行在vim和Dropbox里開啟一個臨時文件

我過去喜歡用Emacs里的scratch facility功能。也經常用Vim快速創建臨時文件。下面這兩個函數是使用openssl生成隨機的字符串作為文件名:

function sc {
  gvim ~/Dropbox/$(openssl rand -base64 10 | tr -dc 'a-zA-Z').txt
}

function scratch { gvim ~/Dropbox/$(openssl rand -base64 10 | tr -dc 'a-zA-Z').txt }</pre>

在命令行窗口輸入sc或scratch,一個新的gvim或macvim窗口就會彈出來,里面會加載一個隨機文件名的臨時文件。

技巧五、用命令行下載文件,包括鏈接轉向、HTTPS和安全加密等情況。

下載一個頁面輸出到終端,跟隨鏈接轉向,忽略安全異常:

curl -Lks <some-url>

下載一個鏈接,跟隨鏈接轉向,忽略安全異常:

curl -OLks <some-url/to/a/file.tar.gz>

這里用了很多參數,你可以閱讀這個簡單的curl文檔來了解它們。

技巧六、Bashmarks

你還沒有在.bashrc里使用bashmarks嗎?還在等待什么?它真的非常有用。它能幫你保持歷史操作,跳回到你經常使用的目錄。下面是我的配置文件里腳本,但我想上面的鏈接能提供你更多技巧:

# USAGE:

s bookmarkname - saves the curr dir as bookmarkname

g bookmarkname - jumps to the that bookmark

g b[TAB] - tab completion is available

l - list all bookmarks

save current directory to bookmarks

touch ~/.sdirs function s { cat ~/.sdirs | grep -v "export DIR$1=" > ~/.sdirs1 mv ~/.sdirs1 ~/.sdirs echo "export DIR$1=$PWD" >> ~/.sdirs }

jump to bookmark

function g { source ~/.sdirs cd $(eval $(echo echo $(echo \$DIR_$1))) }

list bookmarks with dirnam

function l { source ~/.sdirs env | grep "^DIR_" | cut -c5- | grep "^.*=" }

list bookmarks without dirname

function l { source ~/.sdirs env | grep "^DIR" | cut -c5- | grep "^.*=" | cut -f1 -d "=" }

completion command for g

function _gcomp { local curw COMPREPLY=() curw=${COMP_WORDS[COMP_CWORD]} COMPREPLY=($(compgen -W '_l' -- $curw)) return 0 }

bind completion command for g to _gcomp

complete -F _gcomp g</pre>

技巧七、從格式化輸出里提取一列(我最常使用的awk技巧)

我幾乎天天都會使用它。真的。經常會有一些輸出,我只需要其中的第二列,或第三列,下面這個命令就能做到這些:

#Sample output of git status -s command:

$ git status -s

M .bashrc ?? .vim/bundle/extempore/

Remove status code from git status and just get the file names

$ git status -s | awk '{print $2}'

.bashrc .vim/bundle/extempore/</pre>

為什么不寫個函數,讓我們隨時都可以用呢?

function col {
  awk -v col=$1 '{print $col}'
}

這使得提取列非常容易,比如,你不想要第一列?簡單:

$ git status -s | col 2

.bashrc .vim/bundle/extempore/</pre>

技巧八、忽略頭x個詞

我對xargs很著迷,我感覺它就像一把快刀。但有時候用它獲得的結果需要調整一下,也許需要取得一些值。例如,你想去掉下面文件影像里的一些信息:

function skip {
    n=$(($1 + 1))
    cut -d' ' -f$n-
}

下面是如何使用它:

  • 使用 docker images 得到下面的輸出:
  • </ul>

    $ docker images

    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE <none> <none> 65a9e3ef7171 3 weeks ago 1.592 GB <none> <none> 7c01ca6c30f2 3 weeks ago 11.1 MB <none> <none> 9518620e6a0e 3 weeks ago 7.426 MB <none> <none> 430707ee7fe8 3 weeks ago 7.426 MB boot2docker/boot2docker latest 1dbd7ebffe31 3 weeks ago 1.592 GB spaceghost/tinycore-x86_64 5.4 f47686df00df 7 weeks ago 11.1 MB durdn/bithub latest df1e39df8dbf 8 weeks ago 100.9 MB <none> <none> c5e6cf38d985 8 weeks ago 100.9 MB nginx latest e426f6ef897e 12 weeks ago 100.2 MB zoobab/tinycore-x64 latest 8cdd417ec611 8 months ago 7.426 MB scratch latest 511136ea3c5a 20 months ago 0 B</pre>

    • 使用上面的函數,你可以獲取所有的IDs:
    • </ul>

      $ docker images | col 3 IMAGE
      65a9e3ef7171
      7c01ca6c30f2
      9518620e6a0e
      430707ee7fe8
      1dbd7ebffe31
      f47686df00df
      df1e39df8dbf
      c5e6cf38d985
      e426f6ef897e
      8cdd417ec611
      511136ea3c5a

      • 進一步處理:
      • </ul>

        docker images | col 3 | xargs

        IMAGE 65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a</pre>

        • 但前面的”IMAGE”字符我也想去掉:
        • </ul>

          docker images | col 3 | xargs | skip 1

          65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a</pre>

          • 完整的寫下來就是這樣:
          • </ul>

            docker rmi $(docker images | col 3 | xargs | skip 1)

            技巧九、創建自己的命令包

            在bash里,你可以很容易的創建自己的命令組件,你可以看一下下面我寫的:

            function dur {
              case $1 in
              clone|cl)
                git clone git@bitbucket.org:nicolapaolucci/$2.git
                ;;
              move|mv)
                git remote add bitbucket git@bitbucket.org:nicolapaolucci/$(basename $(pwd)).git
                git push --all bitbucket
                ;;
              trackall|tr)

            #track all remote branches of a project
            for remote in $(git branch -r | grep -v master ); do git checkout --track $remote ; done
            ;;
            

            key|k)

            #track all remote branches of a project
            ssh $2 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
            ;;
            

            fun|f)

            #list all custom bash functions defined
            typeset -F | col 3 | grep -v _ | xargs | fold -sw 60
            ;;
            

            def|d)

            #show definition of function $1
            typeset -f $2
            ;;
            

            help|h|*) echo "[dur]dn shell automation tools" echo "commands available:" echo " [cl]one, [mv|move]" echo " [f]fun lists all bash functions defined in .bashrc" echo " [def] <fun> lists definition of function defined in .bashrc" echo " [k]ey <host> copies ssh key to target host" echo " [tr]ackall], [h]elp" ;; esac }</pre>

            通過上面的腳本,我可以將ssh key拷貝到任何網站服務器——只需要鍵入 dur key
            user@somehost.

            總結

            你可以試一下我的這個.bashrc文件,或你自己也可以寫一個。

            來自:http://www.techug.com/ten-tips-for-wonderful-bash-productivity

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!