1. 程式人生 > 程式設計 >Shell在程式碼重構中的應用瞭解下

Shell在程式碼重構中的應用瞭解下



程式碼重構(Code refactoring)有時是很枯燥的,字串替換之類的操作不僅乏味,而且還容易出錯,好在有一些工具可用,以PHP為例,如:Rephactor,Scisr等等,不過現成的工具往往意味著不夠靈活,所以今天我要說說Shell在程式碼重構中的應用。

先來個簡單的,假設我們要把PHP檔案中的foo_bar全都替換成fooBar,那麼可以如下:

方法一,使用Sed:

1shell> find /path -name "*.php" -print0 | xargs -0 sed '
2           s/foo_bar/fooBar/g
3       '
複製程式碼

方法二,使用AWK:

1shell> find /path -name "*.php" -print0 | xargs -0 awk '
2           {
3               gsub(/foo_bar/,"fooBar")
4               print
5           }
6       '
複製程式碼

注:為了簡單,我把結果直接列印到終端螢幕了,至於如何儲存,稍後會說明。

接著說個複雜的:假設某個PHP專案,以前使用類之前必須呼叫一個叫『includeClass』的方法,現在改用類自動載入的方式,所以要刪除硬編碼的includeClass呼叫,出於美觀的考慮,如果includeClass下面一行是空行的話,也一起刪除,同時考慮大小寫不敏感的因素。

重構前的程式碼示例:

 101 <?php
 202 includeClass('...');
 303 echo 'a';
 404
 505 echo 'b';
 606 includeClass('...');
 707 includeClass('...');
 808
 909
1010 echo 'c';
1111
1212 echo 'd';
1313 includeClass('...');
1414
1515
1616 echo 'e';
1717 ?>
複製程式碼

重構後的程式碼示例:

 101 <?php
 202 echo 'a';
 303
 404 echo 'b';
 505
 606 echo
'c'; 707 808 echo 'd'; 909 1010 echo 'e'; 1111 ?> 複製程式碼

在動手前,我們需要先摸摸底,瞭解一下大概的情況:

1shell> grep -I -ri includeClass /path | more
複製程式碼

其中,grep命令的引數乍一看不好記,不過只要按照我說的方法記,就永遠不會忘:前面的引數看做英文,後面的引數看做拼音?。至於引數的具體含義,請參閱man檔案。


方法一,使用Sed編寫指令碼script.sh:

 1#!/bin/bash
 2
 3for PHP in $@; do
 4    /bin/sed -i '
 5        /includeClass/I {
 6            h
 7            d
 8        }
 9
10        /^$/ {
11            x
12            /includeClass/Id
13            x
14        }
15
16        h
17    ' $PHP
18done
複製程式碼

注:篇幅所限,我把正則寫的比較簡單

Sed的缺點是程式碼可讀性比較差,優點是程式碼較短。另外內建的『-i』選項可以直接完成儲存,這是我喜歡Sed的原因之一。

方法二,使用AWK編寫指令碼script.sh:

 1#!/bin/bash
 2
 3for PHP in $@; do
 4    TMP=$(mktemp)
 5
 6    /bin/awk '
 7        BEGIN {
 8            IGNORECASE = 1
 9        }
10
11        /includeClass/ {
12            previous = $0
13            next
14        }
15
16        /^$/ {
17            if (previous ~ /includeClass/) {
18                previous = $0
19                next
20            }
21        }
22
23        {
24            previous = $0
25            print
26        }
27    ' $PHP > $TMP
28
29    /bin/cp -f $TMP $PHP
30    /bin/rm -f $TMP
31done
複製程式碼

注:篇幅所限,我把正則寫的比較簡單

AWK的缺點是程式碼比較長,優點是程式碼可讀性較好。另外程式中是通過生成一個唯一的臨時檔案來完成儲存的。

提醒:直接覆蓋原始檔案有時候並不合適,畢竟可能有沒考慮周詳的地方,使用SVN的話就不會有這樣的顧慮了,因為即便覆蓋了原始檔案,也可以在提交前通過“svn diff”命令來檢查對錯,就算是提交了,也可以恢復到以前的版本。

如何呼叫script.sh指令碼呢?這裡給個最一般的例子:

1shell> find /path -name "*.php" -print0 | xargs -0 /path/to/script.sh
複製程式碼

簡單的任務用Sed寫很合適,複雜的任務則最好用AWK寫,具體可以參考Sed One Line和AWK One Line等。


很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務程式碼寫多了沒有方向感,不知道該從那裡入手去提升,對此我整理了一些資料,包括但不限於:分散式架構、高可擴充套件、高效能、高併發、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell指令碼、Docker、微服務、Nginx等多個知識點高階進階乾貨需要的可以免費分享給大家,需要的加群(點選→)此處我的官方群