shell經常使用集錦

a=$( expr 'helloworld20140501.txt' : '.*\([0-9]\{8\}\).*' )
echo $a
linux shell 中能夠將命令的結果賦值給變量,$(命令)這種格式將返回命令執行後的結果字符串
上面命令執行後,變量a的值是20140501
 a=`echo  'helloworld20140501.txt'|sed 's/.*\([0-9]\{8\}\).*/\1/'`
這個命令做用也是同樣,變量a被賦值爲20140501

===========================================================================html

Linux Shell中寫循環時,經常要用到變量的自增,如今總結一下整型變量自增的方法。
我所知道的,bash中,目前有五種方法:
1. i=`expr $i + 1`;
2. let i+=1;
3. ((i++));
4. i=$[$i+1];
5. i=$(( $i + 1 ))
能夠實踐一下,簡單的實例以下:linux

#!/bin/bash
i=0;
while [ $i -lt 4 ];
do
   echo $i;
   i=`expr $i + 1`;
   # let i+=1;
   # ((i++));
   # i=$[$i+1];
   # i=$(( $i + 1 ))
done


另外,對於固定次數的循環,能夠經過seq命令來實現,就不須要變量的自增了;實例以下:正則表達式

#!/bin/bash
for j in $(seq 1 5)
do
  echo $j
done

 

================================================================================shell

在服務器上加了一個服務檢測機制,用到正則來匹配IP和捕獲分組。shell和其餘語言同樣也可使用正則分組捕獲,不過不能使用 $1或\1這樣的形式來捕獲分組,能夠經過數組${BASH_REMATCH}來得到,如${BASH_REMATCH[1]},${BASH_REMATCH[N]}apache

簡單的測試以下所示:ubuntu

 

1數組

2bash

3服務器

4app

5

6

7

8

9

10

11

#!/bin/bash

ip="121.0.2.2"

if [[ $ip =~ ^([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]];then

echo "match"

echo ${BASH_REMATCH[1]}

echo ${BASH_REMATCH[2]}

echo ${BASH_REMATCH[3]}

echo ${BASH_REMATCH[4]}

else

echo "Not match"

fi

 =================================================================================

The command basename is often used to extract the real file name without the file type specific file extension:

1

2

$ basename thisfile.txt .txt

thisfile

Now sometimes you need it the other way around, you might want to have the file extension. There are of course hundreds of ways to do so, but I found this one appealing since it also shows how the commandawk works (which I should learn a bit better I think):

1

2

$ echo "thisfile.txt"|awk -F . '{print $NF}'

txt

The 「-F」 marks the delimiter, 「$NF」 means the last field generated. Seems to be a pretty straightforward tool.

==========================================================================

awk中使用的shell命令,有2種方法:
一。使用system()
二。使用print cmd | 「/bin/bash」
http://www.gnu.org/software/gawk/manual/gawk.html#I_002fO-Functions

一。使用因此system()
awk程序中咱們可使用system() 函數去調用shell命令

如:awk 'BEGIN{system("echo abc")}' file

echo abc 就會作爲「命令行」,由shell來執行,因此咱們會獲得如下結果:



root@ubuntu:~# awk 'BEGIN{system("echo abc")}'
abc
root@ubuntu:~#


root@ubuntu:~# awk 'BEGIN{v1="echo";v2="abc";system(v1" "v2)}'
abc
root@ubuntu:~#


root@ubuntu:~# awk 'BEGIN{v1="echo";v2="abc";system(v1 v2)}'
/bin/sh: echoabc: command not found
root@ubuntu:~#


root@ubuntu:~# awk 'BEGIN{v1=echo;v2=abc;system(v1" "v2)}'
root@ubuntu:~#

從上面的例子,咱們簡單的分析一下awk是怎樣調用system的:
若是system()括號裏面的參數沒有加上雙引號的話,awk認爲它是一個變量,它會從awk的變量裏面把它們先置換爲常量,而後再回傳給shell

若是system()括號裏面的參數有加上雙引號的話,那麼awk就直接把引號裏面的內容回傳給shell,做爲shell的「命令行」



二。使用print cmd | 「/bin/bash」
root@ubuntu:~# awk 'BEGIN{print "echo","abc"| "/bin/bash"}'
abc
root@ubuntu:~#


root@ubuntu:~# awk 'BEGIN{print "echo","abc",";","echo","123"| "/bin/bash"}'
abc
123
root@ubuntu:~#


三。總結
不管使用system()仍是print cmd | 「/bin/bash」
awk都是新開一個shell,在相應的cmdline參數送回給shell,因此要注意當前shell變量與新開shell變量問題

==========================================================================

獲取文件名和後綴名

代碼:

file=」thisfile.txt」

echo 「filename: ${file%.*}」

echo 「extension: ${file##*.}」

輸出:

filename: thisfile

extension: txt

附:

Bash字符串處理

基於Pattern Matching的子串替換

${STR/$OLD/$NEW}

替換第一個。

${STR//$OLD/$NEW}

替換全部。

注意:不能使用正則表達式,只能使用?*的Shell擴展。只能用shell通配符如 * ?  [list] [!list] [a-z]。

${STR/#$OLD/$NEW}

替換開頭。若是STR以OLD串開頭,則替換。

${STR/%$OLD/$NEW}

替換結尾。若是STR以OLD串結尾,則替換。

 

[user@laptop ~]# STR=」Hello World」 

[user@laptop ~]# echo ${STR/o/O} 

HellO World

[user@laptop ~]# echo ${STR//o/O} 

HellO WOrld

[user@laptop ~]# STR=」Hello World」 

[user@laptop ~]# echo ${STR/#He/he} 

hello World

[user@laptop ~]# echo ${STR/#o/he} 

Hello World

[user@laptop ~]# echo ${STR/%He/he} 

Hello World

[user@laptop ~]# echo ${STR/%ld/lD} 

Hello WorlD

 

若是被替換串包含/字符,那麼要轉義,寫成\/。

 

[user@laptop ~]# filename=」/user/admin/monitoring/process.sh」 

[user@laptop ~]# echo ${filename/#\/user/\/tmp} 

/tmp/admin/monitoring/process.sh

[user@laptop ~]# echo ${filename/%.*/.ksh} 

/user/admin/monitoring/process.ksh

[user@laptop ~]#

 

將環境變量PATH的各個目錄分開,每行顯示一個。

echo -e ${PATH/:/\n}

 

[user@laptop ctmw]# echo $PATH 

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/apache/apache-ant-1.7.1/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/user/bin

[user@laptop ctmw]# echo -e ${PATH//:/’\n’} 

/usr/kerberos/sbin

/usr/kerberos/bin

/usr/apache/apache-ant-1.7.1/bin

/usr/local/sbin

/usr/local/bin

/sbin

/bin

/usr/sbin

/usr/bin

/user/bin

[user@laptop ctmw]# echo 「${PATH//:/$’\n’}」 

/usr/kerberos/sbin

/usr/kerberos/bin

/usr/apache/apache-ant-1.7.1/bin

/usr/local/sbin

/usr/local/bin

/sbin

/bin

/usr/sbin

/usr/bin

/user/bin

 

基於Pattern Matching的子串刪除

子串刪除是一種特殊的替換

${STR/$SUB}

將STR中第一個SUB子串刪除

${STR//$SUB}

將STR中全部SUB子串刪除

${STR#$PREFIX}

去頭,從開頭去除最短匹配前綴

${STR##$PREFIX}

去頭,從開頭去除最長匹配前綴

${STR%$SUFFIX}

去尾,從結尾去除最短匹配後綴

${STR%%$SUFFIX}

去尾,從結尾去除最長匹配後綴

注意:常常會記錯#和%的含義,有一個幫助記憶的方法

看一下鍵盤,#在$以前,%在$以後,就知道#去頭,%去尾。

注意:不能使用正則表達式,只能使用?*的Shell擴展。

 

[user@laptop ~]# STR=」Hello World」 

[user@laptop ~]# echo ${STR#He} 

llo World

[user@laptop ~]# echo ${STR#He*o} 

World

[user@laptop ~]# echo ${STR##He*o} 

rld

[user@laptop ~]# PREFIX=」*o」 

[user@laptop ~]# echo ${STR#$PREFIX} 

World

[user@laptop ~]# echo ${STR##$PREFIX} 

rld

[user@laptop ~]# echo ${STR%o*} 

Hello W

[user@laptop ~]# echo ${STR%%o*} 

Hell

[user@laptop ~]# SUFFIX=」o*」 

[user@laptop ~]# echo ${STR%$SUFFIX} 

Hello W

[user@laptop ~]# echo ${STR%%$SUFFIX} 

Hell

 

典型應用:獲得文件的擴展名

[user@laptop ~]# FILE=hello.jpg 

[user@laptop ~]# echo ${FILE##*.} 

jpg

 

使用sed命令實現正則表達式替換

使用sed命令能夠進行正則表達式的替換。

echo 「$STR」 | sed 「s/$OLD/$NEW/」

將STR中的OLD子串替換成NEW。

 

[user@laptop ~]# STR=」123456789″ 

[user@laptop ~]# echo 「$STR」 | sed s/345/OK/ 

12OK6789

[user@laptop ~]# OLD=345 

[user@laptop ~]# NEW=OK 

[user@laptop ~]# echo 「$STR」 | sed 「s/$OLD/$NEW/」 

12OK6789

 

使用tr命令實現字符集合的替換

使用tr命令能夠實現字符的替換,而且能夠是從一批字符到另外一批字符的替換。好比小寫字母變成大寫字母,或者反過來。

 

[user@laptop ~]# echo 「bash」 | tr 「[a-z]」 「[b-z]」 

cbti

上面的命令是將原串中的a替換成b,被替換成c,以此類推。

 

網上問題:Linux中 有沒有一個命令能夠將 字符串中出現的 +或者- 替換成對應的-或者+  即 「+」 ——> 「-」  「-」——>」+」  例如 GMT+8-9變成 GMT-8+9

 

[user@laptop ~]# echo 「GMT+8-9″ | sed ‘s/-/#/g’ | sed ‘s/+/-/g’ | sed ‘s/#/+/g’ 

GMT-8+9

上面是網上提供的答案。若是用tr來實現,更簡潔些。 

[user@laptop ~]# echo 「GMT+8-9″ | tr 「+-」 「-+」 

GMT-8+9

 

路徑字符串的處理

dirname ${FULLPATH}

取目錄部分。

basename ${FULLPATH}

取文件名部分。

basename ${FULLPATH} ${EXT}

取文件名部分,而且去掉指定的擴展名。

[user@laptop ~]# FULLPATH=/user/work/project/backup.tar.gz 

[user@laptop ~]# dirname 「$FULLPATH」 

/user/work/project

[user@laptop ~]# basename 「$FULLPATH」    

backup.tar.gz

[user@laptop ~]# basename 「$FULLPATH」 .gz 

backup.tar

[user@laptop ~]# basename 「$FULLPATH」 .tar 

backup.tar.gz

[user@laptop ~]# basename 「$FULLPATH」 .tar.gz 

backup

取目錄部分:${FULLPATH%/*}    

(相似 dirname 「$FULLPATH」)

取文件名稱:FILE=${FULLPATH##*/}

(相似 basename 「$FULLPATH」)

取最短基本名稱:${FILE%%.*}

取最長基本名稱:${FILE%.*}

取最短擴展名:${FILE##*.}  或者  ${FULLPATH##*.}

取最長擴展名:${FILE#*.}  或者  ${FULLPATH#*.}

 

[user@laptop ~]# FULLPATH=/user/work/project/backup.tar.gz 

[user@laptop ~]# echo ${FULLPATH%/*} 

/user/work/project

[user@laptop ~]# dirname 「$FULLPATH」 

/user/work/project

[user@laptop ~]# FILE=${FULLPATH##*/} 

[user@laptop ~]# echo $FILE 

backup.tar.gz

[user@laptop ~]# basename 「$FULLPATH」 

backup.tar.gz

[user@laptop ~]# echo ${FILE%%.*} 

backup

[user@laptop ~]# echo ${FILE%.*} 

backup.tar

[user@laptop ~]# echo ${FILE##*.} 

gz

[user@laptop ~]# echo ${FILE#*.} 

tar.gz

=============================================================================

相關文章
相關標籤/搜索