shell中关于# %的用法

在上篇文章 “更改文件名“中,一CU网友给出了一个答案
ls *.flac|while read file
do
echo mv "${file}" "${file#*-}";
done

很好奇${file#*-}字符串中#*-的作用,于是在网上看到一些内容是说明这些东西的:
来自 http://www.boobooke.com/bbs/thread-148390-1-1.html,内容如下:

关于# %的用法问题!今天就在这里说下吧!有些用到的也不是很多!自己之前在写一个脚本的时候用到过!
主要是就是#和%和:的一些特殊用法:
# 用在变量名前面可以达到统计字符个数的功能
tom@sexly:~$ a=”www.google.com”
tom@sexly:~$ echo ${#a}
14

# 用在变量之后的时候可以达到截取字符的功能(只匹配一次)
tom@sexly:~$ a=”www.google.com”
tom@sexly:~$ echo ${a#*.} 这里截取.(第一个点)后面的所有内容
google.com

## 和单个#功能基本相同,但是他会匹配到最后
tom@sexly:~$ a=”www.google.com”
tom@sexly:~$ echo ${a##*.} 这里截取了最后一个点的内容
com

% 和%% 他们功能与#和##基本相同 最不过他们是截取的内容是相反的
tom@sexly:~$ a=”www.google.com”
tom@sexly:~$ echo ${a%.*}
http://www.google
tom@sexly:~$ a=”www.google.com”
tom@sexly:~$ echo ${a%%.*}
www

:(冒号) 其功能也是截取字符串
格式为 :起始[:长度] 省略长度,系统默认截取到最后,起始从0开始
tom@sexly:~$ echo ${a:4}
google.com
tom@sexly:~$ echo ${a:4:6}
google

从上面可以看到,CU网友出给的答案${file#*-}的作用是截取 后面的内容.

shell中[ – ]

原来在shell中,[ ]中使用的-(范围)是从0-9,如果是20到29则要2[0-9]
一个简单的例子:
#!/bin/sh
time1=`date +%H`
case ${time1} in
0[1-9]|[10-12])
echo "now is lunch"
exit 0
;;
1[3-9]|2[0-4])
echo "now is aftermoon"
exit 0
;;
esac

shell统计访问日志的IP并排序(很笨的方法)

1.grep “[1-9]{1,3}.[1-9]{1,3}.[1-9]{1,3}.[1-9]{1,3}” nginx.access.log | awk ‘{ print $1 }’ | sort | uniq -c | sort -r | head -n 2
2.只针对nginx的log格式为$remote_addr – $remote_user [$time_local] “$request“ $status $body_bytes_sent “$http_referer””$http_user_agent” “$http_x_forwarded_for”的排序
cut -d -f 1 nginx.access.log | awk ‘{ print $1 }’ | sort | uniq -c | sort -r | head -n 2
不过如果是这样可以修改-d 和-f 去工作

eval

今天看了rc.subr,发现shell的一个用法eval不是很懂,于是在网上查了下,发现一牛人的说法是:

eval执行后面的字符串,这里实际上完成了两命令替换!

上面我理解的意思是:重复执行一行代码两次.

而我看到rc.subr里面的一段代码是

eval _value=$${1}

会不会是以下的意思呢?

例如${1}是name,那_value就储存$name的值.因为是eval,它执行了$${1}.也就是先执行了${1}(例如是name),然后再执行$name, 不过在eval看来,$被再次执行时就变成了$,也就是变成了$name.

下面一个小脚本可以说明上面我的看法

#!/bin/sh

File="/etc/resolv.conf"

echo "File is ${File}"

eval echo "File is ${File}"