SHELL字串使用總結

weixin_34377065發表於2014-08-15

1、獲取字串的長度,${#str}

#設定字串
$ str="liqiu"
#列印字串
$ echo $str
liqiu
#繼續列印字串
$ echo ${str}
liqiu
#列印字串長度
$ echo ${#str}
5

2、在段落後面增加空行

#!/bin/bash
# paragraph-space.sh
 
# 在一個單倍行距的文字檔案中插入空行.
# Usage: $0 < FILENAME
  
MINLEN=45        # 可能需要修改這個值。假定行的長度小於$MINLEN所指定的長度的時候才認為此段結束。
 
while read line  # 提供和輸入檔案一樣多的行...
do
   echo "$line"   # 輸入所讀入的行本身.
  
   len=${#line}
   if [ "$len" -lt "$MINLEN" ]
     then echo    # 在短行(譯者注: 也就是小於$MINLEN個字元的行)後面新增一個空行.
   fi 
done

exit 0

3、檢視字串出現的位置

stringZ=abcABC123ABCabc
echo `expr index "$stringZ" C12`             # 6
 
echo `expr index "$stringZ" 1c`              # 3

4、字串替換

curr_date="2014-08-08"
table_curr_date=${curr_date//-/_} #結果:2014_08_08

5、字串分割

5.1 基本方法

#1. bash提供的陣列資料結構,它是以數字為下標的,和C語言從0開始的下標一樣
$ var="get the length of me"
$ var_arr=($var)    #這裡把字串var存放到字串陣列var_arr中了,預設以空格作為分割符
$ echo ${var_arr[0]} ${var_arr[1]} ${var_arr[2]} ${var_arr[3]} ${var_arr[4]}
get the length of me
$ echo ${var_arr[@]}    #這個就是整個字串所有部分啦,這裡可以用*代替@,下同
get the length of me
$ echo ${#var_arr[@]}    #記得上面求某個字串的長度麼,#操作符,如果想求某個陣列元素的字串長度,那麼就把@換成下標吧
5
# 你也可以直接給某個陣列元素賦值
$ var_arr[5]="new_element"
$ echo ${var_arr[5]}
6
$ echo ${var_arr[5]}
new_element
# bash裡頭實際上還提供了一種類似於“陣列”的功能,即"for i in 用指定分割符分開的字串" 的用法 即,你可以很方便的獲取某個字串的某個部分
$  for i in $var; do echo -n $i" "; done;
get the length of me  

5.2 awk方法

#2. awk裡頭的陣列,注意比較它和bash提供的陣列的異同
# split把一行按照空格分割,存放到陣列var_arr中,並返回陣列的長度。注意:這裡的第一個元素下標不是0,而是1
$ echo $var | awk '{printf("%d %s\n", split($0, var_arr, " "), var_arr[1]);}'
5 get
# 實際上,上面的操作很類似awk自身的行處理功能:awk預設把一行按照空格分割為多個域,並可以通過$1,$2,$3...來獲取,$0表示整行
# 這裡的NF是該行的域的總數,類似於上面陣列的長度,它同樣提供了一種通過“下標”訪問某個字串的功能
$ echo $var | awk '{printf("%d | %s %s %s %s %s | %s\n", NF, $1, $2, $3, $4, $5, $0);}'
5 | get the length of me | get the length of me
# awk的“陣列”功能何止於此呢,看看它的for引用吧,注意,這個和bash裡頭的for不太一樣,i不是元素本身,而是下標
$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",var_arr);}'
get the length of me 
$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",i);}'
1 2 3 4 5 
# awk還有更“厲害”的處理能力,它的下標可以不是數字,而可以是字串,從而變成了“關聯”陣列,這種“關聯”的作用在某些方便將讓我們非常方便
# 比如,我們這裡就實現一個非凡的應用,把某個檔案中的某個系統呼叫名替換成地址,如果你真正用起它,你會感慨它的“鬼斧神工”的。
# 這就是我在一個場合最好才發現的隨好的實現方案:有興趣看看awk手冊帖子中我在3樓回覆的例項吧。
$ cat symbol 
sys_exit
sys_read
sys_close
$ ls /boot/System.map*
$ awk '{if(FILENAME ~ "System.map") map[$3]=$1; else {printf("%s\n", map[$1])}}' /boot/System.map-2.6.20-16-generic symbol 
c0129a80
c0177310
c0175d80
# 另外,awk還支援刪除某個陣列元素,如果你不用了就可以用delete函式給刪除掉。如果某些場合有需要的話,別忘了awk還支援二維陣列。

6、字串分割

$ var="get the length of me"
$ echo ${var%% *} #從右邊開始計算,刪除最左邊的空格右邊的所有字元 get $ echo ${var% *} #從右邊開始計算,刪除第一個空格右邊的所有字元 get the length of $ echo ${var##* } #從左邊開始計算,刪除最右邊的空格左邊的所有字元 me $ echo ${var#* } #從左邊開始計算,刪除第一個空格左邊的所有字元 the length of me

7、字串擷取

// 按照位置取子串,比如從什麼位置開始,取多少個字元
$ var="get the length of me"
$ echo ${var:0:3}
get
$ echo ${var:(-2)}   # 方向相反呢
me
$ echo `expr substr "$var" 5 3` #記得把$var引起來,否則expr會因為空格而解析錯誤
the
$ echo $var | awk '{printf("%s\n", substr($0, 9, 6))}'
length 

$ echo $var | awk '{printf("%s\n", $1);}' # awk把$var按照空格分開為多個變數,依次為$1,$2,$3,$4,$5
get
$ echo $var | awk '{printf("%s\n", $5);}'
me
 
$ echo $var | cut -d" " -f 5  #差點把cut這個小東西忘記啦,用起來和awk類似, -d指定分割符,如同awk用-F指定分割符一樣,-f指定“域”,如同awk的$數字。
 
$ echo $var | sed 's/ [a-z]*//g'  #刪除所有 空格+字母串 的字串,所以get後面的全部被刪除了
get
$ echo $var | sed 's/[a-z]* //g'
me
 
$ echo $var | tr " " "\n" | sed -n 1p #sed有按地址(行)列印(p)的功能,記得先用tr把空格換成行號
get
$ echo $var | tr " " "\n" | sed -n 5p
me
 
// tr也可以用來取子串哦,它也可以類似#和%來“拿掉”一些字串來實現取子串
$ echo $var | tr -d " "
getthelengthofme
$ echo $var | tr -cd "[a-z]" #把所有的空格都拿掉了,僅僅保留字母字串,注意-c和-d的用法
getthelengthofme

 

相關文章