摘要:[Shell Script]字串與檔案處理的小技巧大全(也許會不斷新增)
SV是使用bash shell, 也就是開頭#!/bin/sh的那種~
因為處理檔案有太多東西是會用到但是總在網上找個半天(因為原本的方法也很難找到是在哪寫過),
所以以後就有專門給自己看得指令大全!
要是真的那個文件發生意外,至少還有這裡做紀錄~
1.去除第一個字(去除前n個字就多加.)
echo $string | sed 's/^.//'
2.字串取代(因為檔案中的字串取代比較常見,僅記錄純字串的)
echo $string | sed -r 's/str1/str2/g'
3.找字串存在檔案中的那一行
grep -n $query $file
不過會跑出$query,
像是$query=123
就會跑出:
12:123
表示123在檔案的第12行,所以記得要 | awk -F':' '{print $1}'
4.從檔案某一行取代整串字
聽起來很簡單,但是SV用很笨的方法,剛好搭配上述的第三個小技巧,中間會有兩個暫存檔:
oldLine=$(grep -n $query $file | awk -F':' '{print $1}')
sed $oldLine"i$newKey" "$file" > "$file"".tmps2"
// 會將資料插入特定的行
nextLine=`expr $oldLine + 1`
sed -e $nextLine'd' "$file"".tmps2" > "$file"".tmps"
// 接著刪除某一行的下一行(因為插入的是新資料,舊資料還在下一行)
rm "$file"".tmps2"
//刪除暫存的檔案
mv "$file"".tmps" "$file"
//將最後的暫存檔案取代成原本的檔案
5.去掉字串的最後一個字
這個應用是因為,常常有for迴圈做字串累加,
比方1,2,3,4,5,......,n,
結果最後那個n懶得做計數去除(比方判斷是最後一筆時就不累加,),
因此才會用到這方法:
string=${string%?}
6.計算query在檔案中出現的次數
$query是你要找的字串
cat $file | grep -o "$query" | wc -l
記得有特殊字元要加\
像是:
cat $file | grep -o "\[$query]" | wc -l
以上主要是因為左中括號[要被escape掉。(想找到的型式是[123])
7.刪除檔案中的第n~m行
#刪除檔案中的3~18行
startLine=3
endLine=18
sed -e "$startLine,$endLine"d $file > $file.tmp
mv -f $file.tmp $file
以上幾乎都是網路上找到的方法,很感謝stackoverflow的大大們~
另外,我一直困擾著一行一行讀取檔案的方法,
通常會用while:
while read line; do
echo $line
done < $file
或者for:
for line in $(cat $file)
do
echo $line
done
不過for的風險在於他更趨近於用空格來讀檔~
我試過的最後,檔案內容一長(也不用上萬行,僅需10幾行),
若是要從網頁讀檔(用post或get的httprequest抓shell script結果),
都會很久(因為他每跑一個迴圈就是一段時間,1筆1秒,10筆就要跑10秒)......
假設你的內容很簡單、有規律(比方日期+資訊→2014/11/20 第一筆資料),
我個人會傾向於在shell script抓資料時直接用cat。
你會納悶,那麼我從client端抓資料時,即使檔案有\n,使用者介面就是不領情,還是給他連起來呀!
那就是重點了!字串剖析的部分應該由client端(像是javascript)來做會比較快速!
但如果你的資料真的很醜、沒有規則......那這資料還有意義嗎!!!(開玩笑地)
(我想就算是server端要剖析應該也不容易吧......)
那你就只好另請高明了~
最後,雖然很簡單,以上的方法如果你要弄成變數,
只要這樣(以第三條為例):
var=$(grep -n $query $file | awk -F':' '{print $1}')
這樣變數var就會等於你用字串搜尋檔案的那一行號囉~
也就是用$()包起你的指令再丟給變數~
8.刪除某個檔案的某行
sed -e "$line"d "$file" > "$file"".tmp"
mv "$file"".tmp" "$file"
9.插入到某檔案的特定行
if n == specific line
sed "ni$new" "$file" > "$file"".tmp"
mv "$file"".tmp" "$file"
10.乘法
`expr 1 + 4 \* $number + 1`
11.刪除檔案的最後一行
cp $file $file.tmp
sed '$ d' $file.tmp > $file
rm -f $file.tmp
12.取代檔案中的字串
sed -i "s/$old/$new/g" "$file"
13.讀取檔案前n筆
sed -n 1,np $file
14.一行一行讀檔(用while)並找出想要的行數
countTest=0
while read line
do
countTest=`expr $countTest + 1`
if [ "$line" == "$query" ]; then
countPage=$countTest
fi
done <${file}
15.排程-跑php執行檔案
先打開排程編輯軟體
crontab -e
接著依要求撰寫。
例如:每10秒執行一次:
* * * * * /usr/bin/php /var/www/html/Test/test.php
* * * * * sleep 10; /usr/bin/php /var/www/html/Test/test.php
* * * * * sleep 20; /usr/bin/php /var/www/html/Test/test.php
* * * * * sleep 30; /usr/bin/php /var/www/html/Test/test.php
* * * * * sleep 40; /usr/bin/php /var/www/html/Test/test.php
* * * * * sleep 50; /usr/bin/php /var/www/html/Test/test.php
16.編輯大檔案的作法(技巧):
用字串比對、行數或任何方式抓到需要編輯的部分到smallpart檔案,
在smallpart編輯完後,
合併成原本的檔案(因此檔案未合併前有part1,smallpart,part2).tmp
mv file.tmp file
17. 傳檔案至遠端
wget -P 目的資料夾 檔案
18.從遠端抓檔案並覆蓋原本檔案
wget -O 路徑與檔名
19. 取得後n碼
test="1234567890"
result=$(echo $test | grep -o '...$')
結果(後3碼):
890
20.取得字串中的第幾個字
result=`expr substr "$test" n 1`
test="123456"
result=`expr substr "$test" 2 1`
結果 2
21.使用動態變數
方法一:
count=2
let n$count=123
test=n$count
echo ${!test}
結果123(形同echo出n2,而n2=123)
方法二:
count=3
declare "n"$count=456
echo $n3
結果456(用declare產生變數)
22. 刪除檔案的^M
有時候從Windows系統將檔案copy到Linux系統時,檔案會有^M
所以這樣刪除:
sed -i -e 's/.$//' $FILE
$FILE是檔案名稱(或加路徑的檔案名稱)
23. 資料夾中找出現特殊字串的檔案
grep -rnw '/dir/' -e "query"