linux之string字符串操作

#计算字符串的长度
echo ${#str} #12

#位置参数有关操作


echo ${#*} #位置参数的个数
echo ${#@} #位置参数的个数和上面的效果一样
echo $* #把所有的位置参数作为一个字符串输出
echo $@ #效果同上


#字串截取


#
# ${string#substring}
# 从$string的左边第一个字符截掉第一个匹配的$substring
# ${string##substring}
# 从$string的左边第一个字符截掉最后一个个匹配的$substring
#
#从左边开始
echo ${str#a*c} #a到c的最短匹配
echo ${str##a*c} #a到c的最长匹配

#从右边开始
echo ${str%a*C} #从右边的最后一个字符开始寻找a到B的最短匹配
echo ${str%%a*B} #从右边最后一个字符开始寻找a到B的最长匹配
#这里找不到模式

#==取子串==


# ${string:position}
# ${string:positon:length}
#
echo ${str:2} #从第2个位置开始提取字符串的值
echo ${str:2:3} #从第2个位置开始提取长度为3个字符的值
#反向提取子串
echo ${str:(-2)} #从反向的第2个位置开始提取字符串
echo ${str:(-2):6} #从反向的第2个字符的位置开始提取长度为6个字符的串(:(不可能把)
#总共的字符长度只有2个怎么提取6个呢呵呵
echo ${str:(-6):3} #6个中提出3个总可以了把

#位置参数的提取

echo ${*:2} #从第二个位置参数开始提取后面所有位置参数的值
echo ${*:2:3} #从第二个位置参数开始提取3个位置参数的值



补充:

1)echo abcdefg | awk '{print substr($1,length($1)-2,3)}' #efg , 从倒数第三个,即正数第五个,取3个字符。

2)echo $string |cut -c 2-3 (取string 的第2到第3个字符)






#=子串替换=


# ${string/substring/replacement}
# 使用$replacement来替换第一个匹配的$substring.
# ${string//substring/replacement}
# 使用$replacement来替换所有匹配的$substring.
#
# ${string/#substring/replacement}
# 如果$substring匹配$string的开头部分,那么就用$replacement来替换$substring.
# ${string/%substring/replacement}
# 如果$substring匹配$string的结尾部分,那么就用$replacement来替换$substring.
#
str1="123abcABCab12"

echo ${str1/12/hover} #仅仅替换了第一个
echo ${str1//12/hover} #替换了所有的



echo ${str1/#12/hover} # 从头开始匹配12,如果找到做替换
echo ${str1/%12/hover} # 从尾开始匹配12,如果找到做替换



#字符串定位

str=aakeywordbb

startpos=$(echo $str|awk '{print index($str,"keyword")}')
echo $startpos #输出2(注意从0开始计算,即第一个a的位置为0)















1,截取
方法一:
echo $a|awk '{print substr( ,1,8)}'
substr是awk中的一个子函数,对第一个参数的进行截取,从第一个字

符开始,共截取8个字符,如果不够就从第二个字符中补
方法二
echo $a|cut -b2-8
cut:对标准输入的字符串进行处理
cut -bn-m:以byte为单位,从第n个byte开始,取m个
cut -bn,m:以byte为单位,截取第n,m个byte
cut -b-n,m:以byte为单位,截取1-n,和第m个
-c:以charactor为单位
-d:指定分隔符,默认为tab
-s:使标准输入中没有delimeter
cut -f1:截取第1个域
方法三
a=123456
echo $
方法四
使用sed截取字符串的最后两位
echo $test |sed 's/\(.*\)\(..\)$//'
截取字符串的前2位
echo $test |sed 's/^\(..\)\(.*\)//'
欢迎访问007电脑资讯
2,比较
好像没有什么可以比较的
3,连接
$a$b
或者
$string
4,翻转
方法一:
使用rev命令
方法二:
编写脚本实现
#!/usr/bin/awk -f
################################################################
# Description : duplicate rev in awk
################################################################
{
revline = ""
for (i=1;i<=length;i++)
{
revline = substr(,i,1) revline
}
}
END{print revline}

5,匹配
grep
egrep
fgrep
6,排序
7,替换
bash中:
%x=abcdabcd
%echo $ # 只替换一个
bbcdabcd
%echo $ # 替换所有
bbcdbbcd
sh中:
??
如何替换/
使用sed
替换所有匹配
echo $test |sed 's/xx/yy'
替换单个匹配
??
8,得到字符串的长度:
bash当中
$
或者
expr "$VAR" : '.*'
9,判断字符串是否为数字
10,得到字符串中某个字符的重复次数
echo $a |tr "x" "\n" |wc -l
得到的结果需要减去1
或者 echo $a |awk -F"x" '{print NF-1}'
11,得到字符串中某个string的重复次数 007电脑资讯
12,将一批文件中的所有string替换
for i in file_list
do
vi $i <<-!
:g/xxxx/s//XXXX/g
:wq
!
done
13,如何将字符串内每两个字符中间插入一个字符
使用sed
echo $test |sed 's/../&[insert char]/g'

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


象专业人员那样截断字符串

尽管 basename 和 dirname 是很好的工具,但有时可能需要执行更高级的字符串“截断”,而不只是标准的路径名操作。当需要更强的说服力时,可以利用 bash 内置的变量扩展功能。已经使用了类似于 ${MYVAR} 的标准类型的变量扩展。但是 bash 自身也可以执行一些便利的字符串截断。看一下这些例子:


第一种方法:

${varible##*string} 从左向右截取最后一个string后的字符串

${varible#*string}从左向右截取第一个string后的字符串

${varible%%string*}从右向左截取最后一个string后的字符串

${varible%string*}从右向左截取第一个string后的字符串

"*"只是一个通配符可以不要


$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg

在第一个例子中,输入了 ${MYVAR##*fo}。它的确切含

义是什么?基本上,在 ${ } 中输入环境变量名称,两个 ##,然后是通配符 ("*fo")。然后,bash 取得 MYVAR,找到从字符串 "foodforthought.jpg" 开始处开始、且匹配通配符 "*fo" 的 最长 子字符串,然后将其从字符串的开始处截去。刚开始理解时会有些困难,为了感受一下这个特殊的 "##" 选项如何工作,让我们一步步地看看 bash 如何完成这个扩展。首先,它从 "foodforthought.jpg" 的开始处搜索与 "*fo" 通配符匹配的子字符串。以下是检查到的子字符串:


f
fo MATCHES *fo
foo
food
foodf
foodfo MATCHES *fo
foodfor
foodfort
foodforth
foodfortho
foodforthou
foodforthoug
foodforthought
foodforthought.j
foodforthought.jp
foodforthought.jpg



在搜索了匹配的字符串之后,可以看到 bash 找到两个匹配。它选择最长的匹配,从初始字符串的开始处除去,然后返回结果。

上面所示的第二个变量扩展形式看起来与第一个相同,但是它只使用一个 "#" -- 并且 bash 执行 几乎同样的过程。它查看与第一个例子相同的子字符串系列,但是 bash 从初始字符串除去 最短 的匹配,然后返回结果。所以,一查到 "fo" 子字符串,它就从字符串中除去 "fo",然后返回 "odforthought.jpg"。

这样说可能会令人十分困惑,下面以一简单方式记住这个功能。当搜索最长匹配时,使用 ##(因为 ## 比 # 长)。当搜索最短匹配时,使用 #。看,不难记吧!等一下,怎样记住应该使用 '#' 字符来从字符串开始部分除去?很简单!注意到了吗:在美国键盘上,shift-4 是 "$",它是 bash 变量扩展字符。在键盘上,紧靠 "$" 左边的是 "#"。这样,可以看到:"#" 位于 "$" 的“开始处”,因此(根据我们的记忆法),"#" 从字符串的开始处除去字符。您可能要问:如何从字符串末尾除去字符。如果猜到我们使用美国键盘上紧靠 "$" 右边 的字符 ("%),那就猜对了。这里有一些简单的例子,解释如何截去字符串的末尾部分:



$ MYFOO="chickensoup.tar.gz"
$ echo ${MYFOO%%.*}
chickensoup
$ echo ${MYFOO%.*}
chickensoup.tar



正如您所见,除了将匹配通配符从字符串末尾除去之外,% 和 %% 变量扩展选项与 # 和 ## 的工作方式相同。请注意:如果要从末尾除去特定子字符串,不必使用 "*" 字符:



MYFOOD="chickensoup"
$ echo ${MYFOOD%%soup}
chicken

在此例中,使用 "%%" 或 "%" 并不重要,因为只能有一个匹配。还要记住:如果忘记了应该使用 "#" 还是 "%",则看一下键盘上的 3、4 和 5 键,然后猜出来。


第二种方法:${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。


可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。

试着在 bash 中输入以下行:



$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga



这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。

应用字符串截断


现在我们已经学习了所有截断字符串的知识,下面写一个简单短小的 shell 脚本。我们的脚本将接受一个文件作为自变量,然后打印:该文件是否是一个 tar 文件。要确定它是否是 tar 文件,将在文件末尾查找模式 ".tar"。如下所示:

mytar.sh -- 一个简单的脚本

#!/bin/bash

if [ "${1##*.}" = "tar" ]
then
echo This appears to be a tarball.
else
echo At first glance, this does not appear to be a tarball.
fi



要运行此脚本,将它输入到文件 mytar.sh 中,然后输入 "chmod 755 mytar.sh",生成可执行文件。然后,如下做一下 tar 文件试验:



$ ./mytar.sh thisfile.tar
This appears to be a tarball.
$ ./mytar.sh thatfile.gz
At first glance, this does not appear to be a tarball.



好,成功运行,但是不太实用。在使它更实用之前,先看一下上面使用的 "if" 语句。语句中使用了一个布尔表达式。在 bash 中,"=" 比较运算符检查字符串是否相等。在 bash 中,所有布尔表达式都用方括号括起。但是布尔表达式实际上测试什么?让我们看一下左边。根据前面所学的字符串截断知识,"${1##*.}" 将从环境变量 "1" 包含的字符串开始部分除去最长的 "*." 匹配,并返回结果。这将返回文件中最后一个 "." 之后的所有部分。显然,如果文件以 ".tar" 结束,结果将是 "tar",条件也为真。

您可能会想:开始处的 "1" 环境变量是什么。很简单 -- $1 是传给脚本的第一个命令行自变量,$2 是第二个,以此类推。



















一、构造字符串
直接构造
STR_ZERO=hello
STR_FIRST="i am a string"
STR_SECOND='success'

重复多次
#repeat the first parm($1) by $2 times
strRepeat()
{
local x=$2
if [ "$x" == "" ]; then
x=0
fi

local STR_TEMP=""
while [ $x -ge 1 ];
do
STR_TEMP=`printf "%s%s" "$STR_TEMP" "$1"`
x=`expr $x - 1`
done
echo $STR_TEMP
}

举例:
STR_REPEAT=`strRepeat "$USER_NAME" 3`
echo "repeat = $STR_REPEAT"

二、赋值与拷贝
直接赋值
与构造字符串一样
USER_NAME=terry

从变量赋值
ALIASE_NAME=$USER_NAME

三、联接
直接联接两个字符串
STR_TEMP=`printf "%s%s" "$STR_ZERO" "$USER_NAME"`
使用printf可以进行更复杂的联接

四、求长
获取字符串变量的长度:${#string}

求字符数(char)
COUNT_CHAR=`echo "$STR_FIRST" | wc -m`
echo $COUNT_CHAR

求字节数(byte)
COUNT_BYTE=`echo "$STR_FIRST" | wc -c`
echo $COUNT_BYTE

求字数(word)
COUNT_WORD=`echo "$STR_FIRST" | wc -w`
echo $COUNT_WORD

五、比较
相等比较 str1 = str2
不等比较 st

r1 != str2

举例:
if [ "$USER_NAME" = "terry" ]; then
echo "I am terry"
fi

小于比较
#return 0 if the two string is equal, return 1 if $1 < $2, else 2strCompare() { local x=0 if [ "$1" != "$2" ]; then x=2 localTEMP=`printf "%s\n%s" "$1" "$2"` local TEMP2=`(echo "$1"; echo "$2") |sort` if [ "$TEMP" = "$TEMP2" ]; then x=1 fi fi echo $x }

六、测试
判空 -z str
判非空 -n str

是否为数字
# return 0 if the string is num, otherwise 1
strIsNum()
{
local RET=1
if [ -n "$1" ]; then
local STR_TEMP=`echo "$1" | sed 's/[0-9]//g'`
if [ -z "$STR_TEMP" ]; then
RET=0
fi
fi
echo $RET
}

举例:
if [ -n "$USER_NAME" ]; then
echo "my name is NOT empty"
fi

echo `strIsNum "9980"`

七、分割
以符号+为准,将字符分割为左右两部分
使用sed
举例:
命令 date --rfc-3339 seconds 的输出为
2007-04-14 15:09:47+08:00
取其+左边的部分
date --rfc-3339 seconds | sed 's/+[0-9][0-9]:[0-9][0-9]//g'
输出为
2007-04-14 15:09:47
取+右边的部分
date --rfc-3339 seconds | sed 's/.*+//g'
输出为
08:00

以空格为分割符的字符串分割
使用awk
举例:
STR_FRUIT="Banana 0.89 100"
取第3字段
echo $STR_FRUIT | awk '{ print $3; }'

八、子字符串
字符串1是否为字符串2的子字符串
# return 0 is $1 is substring of $2, otherwise 1
strIsSubstring()
{
local x=1
case "$2" in
*$1*) x=0;;
esac
echo $x
}
Shell字符串截取
一、Linux shell 截取字符变量的前8位,有方法如下:

1.expr substr “$a” 1 8
2.echo $a|awk ‘{print substr($0,1,8)}’
3.echo $a|cut -c1-8
4.echo $
5.expr $a : ‘\(.\\).*’
6.echo $a|dd bs=1 count=8 2>/dev/null

二、按指定的字符串截取
1、第一种方法:

${varible##*string} 从左向右截取最后一个string后的字符串
${varible#*string}从左向右截取第一个string后的字符串
${varible%%string*}从右向左截取最后一个string后的字符串
${varible%string*}从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要

例子:
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg

2、第二种方法:${varible:n1:n2}:截取变量varible从n1开始的n2个字符,组成一个子字符串。可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:
$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga
这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。

三、按照指定要求分割:
比如获取后缀名
ls -al | cut -d “.” -f2


shell (bash) 比较运算符 运算符 描述 示例
文件比较运算符
-efilename 如果filename存在,则为真 [ -e /var/log/syslog ]
-dfilename

如果filename为目录,则为真 [ -d /tmp/mydir ]
-ffilename 如果filename为常规文件,则为真 [ -f /usr/bin/grep ]
-Lfilename 如果filename为符号链接,则为真 [ -L /usr/bin/grep ]
-rfilename 如果filename可读,则为真 [ -r /var/log/syslog ]
-wfilename 如果filename可写,则为真 [ -w /var/mytmp.txt ]
-xfilename 如果filename可执行,则为真 [ -L /usr/bin/grep ]
filename1-ntfilename2 如果filename1比filename2新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1-otfilename2 如果filename1比filename2旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符[size=-1](请注意引号的使用,这是防止空格扰乱代码的好方法)
-zstring 如果string长度为零,则为真 [ -z "$myvar" ]
-nstring 如果string长度非零,则为真 [ -n "$myvar" ]
string1=string2 如果string1与string2相同,则为真 [ "$myvar" = "one two three" ]
string1!=string2 如果string1与string2不同,则为真 [ "$myvar" != "one two three" ]
算术比较运算符
num1-eqnum2 等于 [ 3 -eq $mynum ]
num1-nenum2 不等于 [ 3 -ne $mynum ]
num1-ltnum2 小于 [ 3 -lt $mynum ]
num1-lenum2 小于或等于 [ 3 -le $mynum ]
num1-gtnum2 大于 [ 3 -gt $mynum ]
num1-genum2 大于或等于 [ 3 -ge $mynum ]







here string可以看成是here document的一种定制形式. 除了COMMAND <<<$WORD, 就什么都没有了, de>$WORDde>将被扩展并且被送入de>COMMANDde>的stdin中.


1 String="This is a string of words." 2 3 read -r -a Words <<< "$String" 4 # "read"命令的-a选项 5 #+ 将会把结果值按顺序的分配给数组中的每一项. 6 7 echo "First word in String is: ${Words[0]}" # This 8 echo "Second word in String is: ${Words[1]}" # is 9 echo "Third word in String is: ${Words[2]}" # a 10 echo "Fourth word in String is: ${Words[3]}" # string 11 echo "Fifth word in String is: ${Words[4]}" # of 12 echo "Sixth word in String is: ${Words[5]}" # words. 13 echo "Seventh word in String is: ${Words[6]}" # (null) 14 # $String的结尾. 15 16 # 感谢, Francisco Lobo的这个建议.



--------------------------------------------------------------------------------

例子 17-13. 在一个文件的开头添加文本

1 #!/bin/bash 2 # prepend.sh: 在文件的开头添加文本. 3 # 4 # Kenny Stauffer所捐助的脚本例子, 5 #+ 本文作者对这个脚本进行了少量修改. 6 7 8 E_NOSUCHFILE=65 9 10 read -p "File: " file # 'read'命令的-p参数用来显示提示符. 11 if [ ! -e "$file" ] 12 then # 如果这个文件不存在, 那就进来. 13 echo "File $file not found." 14 exit $E_NOSUCHFILE 15 fi 16 17 read -p "Title: " title 18 cat - $file <<<$title > $file.new 19 20 echo "Modified file is $file.new" 21 22 exit 0 23 24 # 下边是'man bash'中的一段: 25 # Here St

ring 26 # here document的一种变形,形式如下: 27 # 28 # <<

相关文档
最新文档