存档

‘Shell’ 分类的存档

LINUX下取得字符的字节码

2009年4月15日

With iso8859-1 encoding:

Code:
test ~ $ echo -e "ö" | od -t oC -An
366 012

With utf8 encoding:

Code:
test ~ $ echo -e "ö" | od -t oC -An
303 266 012

作者: admin 分类: Shell 标签:

2009年3月11日
sed 学习笔记(与大家共勉)
声明:这些代码只是为了学习和理解sed命令而为之,并不代表问题的唯一解或最佳解,希望各位拍砖
参考资料:<sed&awk.pdf>等
一. 替换

1.神奇变换(y命令的使用)

sed 'y/ori_letter_list/target_letter_list/' filename
cat filename
1234567890
2345678901
3456789012
4567890123

测试
将文件中1换成A
将文件中2换成B
...
将文件中0换成J

sed 'y/1234567890/ABCDEFGHIJ/' filename
ABCDEFGHIJ
BCDEFGHIJA
CDEFGHIJAB
DEFGHIJABC

注意变换关系是按两个list的位置对应变换,y是一个管局命令,拒绝使用后缀flag/g
list1:1234567890
list2:ABCDEFGHIJ
下面再作一个与前例相反的变换

sed 'y/0987654321/ABCDEFGHIJ/' filename
JIHGFEDCBA
IHGFEDCBAJ
HGFEDCBAJI
GFEDCBAJIH

2.替换每行第一个匹配

sed 's/regexpr/anyword/' filename
sed 's/regexpr/anyword/1' filename

举例:

QUOTE:
cat filename
1234567890 2345678901
3456789012 4567890123
sed 's/5/五/' filename
1234五67890 2345678901
34五6789012 4567890123

3.替换每行第n(如果有的话)个匹配

sed "s/regexpr/anyword/${n}" filename
cat filename
111111111111111111
222222222222222222
333333333333333333
444444444444444444
举例
sed "s/4/ 四 /8" filename
111111111111111111
222222222222222222
333333333333333333
4444444 四 4444444444

4.替换每行所有匹配

cat filename
1234567890 2345678901
3456789012 4567890123
举例:
sed 's/3/三/g' filename
12三4567890 2三45678901
三456789012 456789012三

二.行号处理

1.为文件加行号

sed = filename|sed 'N;s/\n/:/'
cat filename
111111111111111111
222222222222222222
333333333333333333
444444444444444444

举例

sed = filename|sed 'N;s/\n/:/' filename
1:111111111111111111
2:222222222222222222
3:333333333333333333
4:444444444444444444

2.仅为文件中的正文行加行号

sed /./= a|sed '/./N;s/\n/:/'

举例

cat filename
111111111111111111

222222222222222222
333333333333333333

444444444444444444

sed /./= a|sed '/./N;s/\n/:/' filename
1:111111111111111111

3:222222222222222222
4:333333333333333333

6:444444444444444444

三.字串翻转

sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'

举例

echo 1234567890|sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
0987654321

四.选择性输出

1.打印文档奇数行(隔行输出)

sed 'n;d'
sed 'x;$!N;x'
sed -n 'p;n'

1
3
5
7

2.打印偶数行(隔行输出)

sed -n 'n;p'
sed '1d;n;d;'
2
4
6
8

3.删除连续重复行(大量使用了pattern space 文件太大时要注意)

sed '$!N; /^\(.*\)\n\1$/!P; D'     
#使用 $!N 要当心内存溢出

举例

cat file
111111111111111111
222222222222222222
222222222222222222
333333333333333333
444444444444444444
444444444444444444
444444444444444444
444444444444444444
444444444444444444

sed '$!N; /^\(.*\)\n\1$/!P; D' filename
111111111111111111
222222222222222222
333333333333333333
444444444444444444

4.合并上下行并以空格相分隔

sed '$!N;s/\n/ /'

举例

cat file
1234567890
0987654321
执行命令后
1234567890 0987654321

5.将以\符号结尾的行与下行合并并以空格分隔(拼接断行)

sed -e :a -e '/\\$/N; s/\\\n/ /; ta'

举例

cat filename
1 111111111111111111\
2 222222222222222222
3 333333333333333333\
4 444444444444444444

sed -e :a -e '/\\$/N; s/\\\n/ /; ta' filename
1 111111111111111111 2 222222222222222222
3 333333333333333333 4 444444444444444444

6.按关键字拼接行
  如果某行以=开始,则合并到上一行并替代=为空格

sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'

举例

cat file
111111111111111111
222222222222222222
=333333333333333333
444444444444444444

sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D' filename
111111111111111111
222222222222222222 333333333333333333
444444444444444444

7.输出匹配行的下一行

sed -n '/regexpr/{n;p;}' filename

举例

cat filename
1 111111111111111111
2 222222222222222222
3 333333333333333333
4 444444444444444444

sed -n '/^3/{n;p;}' filename
4 444444444444444444

8.显示匹配行的行号并输出匹配行的上行、匹配行、下行

sed -n -e '/regexpr/{=;x;1!p;g;$!N;p;D;}' -e h
举例

cat filename
1 111111111111111111
2 222222222222222222
3 333333333333333333
4 444444444444444444

sed -n -e '/^3/{=;x;1!p;g;$!N;p;D;}' -e h  filename
3                                       #匹配行的行号
2 222222222222222222  #上一行
3 333333333333333333  #匹配行
4 444444444444444444  #下一行

9.删除文档中某标志区域内的关键字匹配行

     删除文档中从being开到end结束的块中包含myword的行

sed '/^begin/,/^end/{/myword/d;}' filename
QUOTE:
cat filename
myword
begin
myword
Number!
myword
Number!
myword
Number!
myword
Number!

end
myword
Number!

测试

QUOTE:
myword
begin
Number!
Number!
Number!
Number!

end
myword
Number!

五.字串解析

1.从字串中解析出两个子串(前2各字符和后9个字符)

echo "WeLoveChinaUnix"|sed -e 'H;s/\(..\).*/\1/;x;s/.*\(.\{9\}\)$/\1/;x;G;s/\n/ /'
We ChinaUnix

2.分解日期串

echo 20030922|sed 's/\(....\)\(..\)\(..\)/\1 \2 \3/'|read year month day
echo $year $month $day
2003 09 22



作者: admin 分类: Shell 标签:

VIM中粘贴格式错乱的解决方法

2009年2月21日

设置

:set paste

如果想要下次使用生效写入/etc/vimrc文件里

作者: admin 分类: Shell 标签:

或许脚本与执行目录的相对位置

2009年1月25日

 有时候脚本需要根据脚本位操作或生成文件 可使用以下方法

#! /bin/bash
md=`dirname $0`
echo $md

作者: admin 分类: Shell 标签:

如何保护自己编写的shell程序

2008年4月28日

要保护自己编写的shell脚本程序,方法有很多,最简单的方法有两种:1、加密 2、设定过期时间,下面以shc工具为例说明:
一、安装shc工具
shc是一个加密shell脚本的工具.它的作用是把shell脚本转换为一个可执行的二进制文件.
 
shc的下载地址:             
http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.6.tgz

安装:
tar zxvf shc-3.8.tgz
cd shc-3.8
make test
make
make test
make strings
make install  这一步需要root权限
 
二、加密方法:
shc -r -f scrīpt-name  注意:要有-r选项, -f 后跟要加密的脚本名.
运行后会生成两个文件,scrīpt-name.x 和 scrīpt-name.x.c
scrīpt-name.x是加密后的可执行的二进制文件.
./scrīpt-name    即可运行.
scrīpt-name.x.c是生成scrīpt-name.x的原文件(c语言)

三、设定期限:
首先使用shc转化为二进制,并加上过期时间,如
./shc -e 12/06/2006 -m "please contact yazjiyao@yahoo.com.cn" -r -f flushvpn.sh
 
 我一般在程序中加入自动更新系统时间 的命令,防止用户更改系统时间。

作者: admin 分类: Shell 标签:

$(( )) 與 $( ) 還有${ } 差在哪?

2008年4月26日

我們上一章介紹了 ( ) 與 { } 的不同,這次讓我們擴展一下,看看更多的變化:$( ) 與 ${ } 又是啥玩意兒呢?

在 bash shell 中,$( ) 與 ` ` (反引號) 都是用來做命令替換用(command substitution)的。
所謂的命令替換與我們第五章學過的變量替換差不多,都是用來重組命令行:
* 完成引號裡的命令行,然後將其結果替換出來,再重組命令行。
例如:

$ echo the last sunday is $(date -d "last sunday" +%Y-%m-%d)

如此便可方便得到上一星期天的日期了... ^_^

在操作上,用 $( ) 或 ` ` 都無所謂,只是我"個人"比較喜歡用 $( ) ,理由是:

1,  ` ` 很容易與 ' ' ( 單引號)搞混亂,尤其對初學者來說。
有時在一些奇怪的字形顯示中,兩種符號是一模一樣的(直豎兩點)。
當然了,有經驗的朋友還是一眼就能分辯兩者。只是,若能更好的避免混亂,又何樂不為呢? ^_^

2, 在多層次的復合替換中,` ` 須要額外的跳脫( \` )處理,而 $( ) 則比較直觀。例如:
這是錯的:

command1 `command2 `command3` `

原本的意圖是要在 command2 `command3` 先將 command3 提換出來給 command 2 處理,
然後再將結果傳給 command1 `command2 ...` 來處理。
然而,真正的結果在命令行中卻是分成了 `command2 ` 與 `` 兩段。
正確的輸入應該如下:

command1 `command2 \`command3\` `

要不然,換成 $( ) 就沒問題了:

command1 $(command2 $(command3))

只要你喜歡,做多少層的替換都沒問題啦~~~  ^_^

不過,$( ) 並不是沒有斃端的...
首先,` ` 基本上可用在全部的 unix shell 中使用,若寫成 shell script ,其移植性比較高。
而 $( ) 並不見的每一種 shell 都能使用,我只能跟你說,若你用 bash2 的話,肯定沒問題...  ^_^

接下來,再讓我們看 ${ } 吧... 它其實就是用來作變量替換用的啦。
一般情況下,$var 與 ${var} 並沒有啥不一樣。
但是用 ${ } 會比較精確的界定變量名稱的範圍,比方說:

$ A=B
$ echo $AB

原本是打算先將 $A 的結果替換出來,然後再補一個 B 字母於其後,
但在命令行上,真正的結果卻是只會提換變量名稱為 AB 的值出來...
若使用 ${ } 就沒問題了:

$ echo ${A}B
BB

不過,假如你只看到 ${ } 只能用來界定變量名稱的話,那你就實在太小看 bash 了﹗
有興趣的話,你可先參考一下 cu 本版的精華文章:

http://www.chinaunix.net/forum/viewtopic.php?t=201843

為了完整起見,我這裡再用一些例子加以說明 ${ } 的一些特異功能:
假設我們定義了一個變量為:
file=/dir1/dir2/dir3/my.file.txt
我們可以用 ${ } 分別替換獲得不同的值:
${file#*/}:拿掉第一條 / 及其左邊的字串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最後一條 / 及其左邊的字串:my.file.txt
${file#*.}:拿掉第一個 .  及其左邊的字串:file.txt
${file##*.}:拿掉最後一個 .  及其左邊的字串:txt
${file%/*}:拿掉最後條 / 及其右邊的字串:/dir1/dir2/dir3
${file%%/*}:拿掉第一條 / 及其右邊的字串:(空值)
${file%.*}:拿掉最後一個 .  及其右邊的字串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一個 .  及其右邊的字串:/dir1/dir2/dir3/my
記憶的方法為:
[list]# 是去掉左邊(在鑑盤上 # 在 $ 之左邊)
% 是去掉右邊(在鑑盤上 % 在 $ 之右邊)
單一符號是最小匹配﹔兩個符號是最大匹配。[/list]
${file:0:5}:提取最左邊的 5 個字節:/dir1
${file:5:5}:提取第 5 個字節右邊的連續 5 個字節:/dir2

我們也可以對變量值裡的字串作替換:
${file/dir/path}:將第一個 dir 提換為 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:將全部 dir 提換為 path:/path1/path2/path3/my.file.txt

利用 ${ } 還可針對不同的變數狀態賦值(沒設定、空值、非空值):
${file-my.file.txt} :假如 $file 沒有設定,則使用 my.file.txt 作傳回值。(空值及非空值時不作處理)
${file:-my.file.txt} :假如 $file 沒有設定或為空值,則使用 my.file.txt 作傳回值。 (非空值時不作處理)
${file+my.file.txt} :假如 $file 設為空值或非空值,均使用 my.file.txt 作傳回值。(沒設定時不作處理)
${file:+my.file.txt} :若 $file 為非空值,則使用 my.file.txt 作傳回值。 (沒設定及空值時不作處理)
${file=my.file.txt} :若 $file 沒設定,則使用 my.file.txt 作傳回值,同時將 $file 賦值為 my.file.txt 。 (空值及非空值時不作處理)
${file:=my.file.txt} :若 $file 沒設定或為空值,則使用 my.file.txt 作傳回值,同時將 $file 賦值為 my.file.txt 。 (非空值時不作處理)
${file?my.file.txt} :若 $file 沒設定,則將 my.file.txt 輸出至 STDERR。 (空值及非空值時不作處理)
${file:?my.file.txt} :若 $file 沒設定或為空值,則將 my.file.txt 輸出至 STDERR。 (非空值時不作處理)

tips:
以上的理解在於, 你一定要分清楚 unset 與 null 及 non-null 這三種賦值狀態.
一般而言, : 與 null 有關, 若不帶 : 的話, null 不受影響, 若帶 : 則連 null 也受影響.

還有哦,${#var} 可計算出變量值的長度:
${#file} 可得到 27 ,因為 /dir1/dir2/dir3/my.file.txt 剛好是 27 個字節...

接下來,再為大家介稍一下 bash 的組數(array)處理方法。
一般而言,A="a b c def" 這樣的變量只是將 $A 替換為一個單一的字串,
但是改為 A=(a b c def) ,則是將 $A 定義為組數...
bash 的組數替換方法可參考如下方法:
${A[@]} 或 ${A[*]} 可得到 a b c def (全部組數)
${A[0]} 可得到 a (第一個組數),${A[1]} 則為第二個組數...
${#A[@]} 或 ${#A[*]} 可得到 4 (全部組數數量)
${#A[0]} 可得到 1 (即第一個組數(a)的長度),${#A[3]} 可得到 3 (第四個組數(def)的長度)
A[3]=xyz 則是將第四個組數重新定義為 xyz ...

諸如此類的....
能夠善用 bash 的 $( ) 與 ${ } 可大大提高及簡化 shell 在變量上的處理能力哦~~~  ^_^

好了,最後為大家介紹 $(( )) 的用途吧:它是用來作整數運算的。
在 bash 中,$(( )) 的整數運算符號大致有這些:
+ - * / :分別為 "加、減、乘、除"。
% :餘數運算
& | ^ !:分別為 "AND、OR、XOR、NOT" 運算。

例:

$ a=5; b=7; c=2
$ echo $(( a+b*c ))
19
$ echo $(( (a+b)/c ))
6
$ echo $(( (a*b)%c))
1

在 $(( )) 中的變量名稱,可於其前面加 $ 符號來替換,也可以不用,如:
$(( $a + $b * $c)) 也可得到 19 的結果

此外,$(( )) 還可作不同進位(如二進位、八進位、十六進位)作運算呢,只是,輸出結果皆為十進位而已:
echo $((16#2a)) 結果為 42 (16進位轉十進位)
以一個實用的例子來看看吧:
假如當前的  umask 是 022 ,那麼新建文件的權限即為:

$ umask 022
$ echo "obase=8;$(( 8#666 &amp; (8#777 ^ 8#$(umask)) ))" | bc
644

事實上,單純用 (( )) 也可重定義變量值,或作 testing:
a=5; ((a++)) 可將 $a 重定義為 6
a=5; ((a--)) 則為 a=4
a=5; b=7; ((a < b)) 會得到  0 (true) 的返回值。
常見的用於 (( )) 的測試符號有如下這些:
[list]<:小於
>:大於
<=:小於或等於
>=:大於或等於
==:等於
!=:不等於[/list]
不過,使用 (( )) 作整數測試時,請不要跟 [ ] 的整數測試搞混亂了。(更多的測試我將於第十章為大家介紹)

怎樣?好玩吧..  ^_^  okay,這次暫時說這麼多...
上面的介紹,並沒有詳列每一種可用的狀態,更多的,就請讀者參考手冊文件囉...

作者: admin 分类: Shell 标签:

找到一篇sed强文:sed1line

2008年3月22日

HANDY ONE-LINERS FOR SED (Unix stream editor)               Mar. 23, 2001
compiled by Eric Pement <pemente@northpark.edu>               version 5.1
Latest version of this file is usually at:
   http://www.student.northpark.edu/pemente/sed/sed1line.txt
   http://www.cornerstonemag.com/sed/sed1line.txt
This file is also available in Portuguese at:
   http://www.lrv.ufsc.br/wmaker/sed_ptBR.html

FILE SPACING:

 # double space a file
 sed G

 # double space a file which already has blank lines in it. Output file
 # should contain no more than one blank line between lines of text.
 sed '/^$/d;G'

 # triple space a file
 sed 'G;G'

 # undo double-spacing (assumes even-numbered lines are always blank)
 sed 'n;d'

NUMBERING:

 # number each line of a file (simple left alignment). Using a tab (see
 # note on '\t' at end of file) instead of space will preserve margins.
 sed = filename | sed 'N;s/\n/\t/'

 # number each line of a file (number on left, right-aligned)
 sed = filename | sed 'N; s/^/     /; s/ *\(.\{6,\}\)\n/\1  /'

 # number each line of file, but only print numbers if line is not blank
 sed '/./=' filename | sed '/./N; s/\n/ /'

 # count lines (emulates "wc -l")
 sed -n '$='

TEXT CONVERSION AND SUBSTITUTION:

 # IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
 sed 's/.$//'               # assumes that all lines end with CR/LF
 sed 's/^M$//'              # in bash/tcsh, press Ctrl-V then Ctrl-M
 sed 's/\x0D$//'            # gsed 3.02.80, but top script is easier

 # IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format
 sed "s/$/`echo -e \\\r`/"            # command line under ksh
 sed 's/$'"/`echo \\\r`/"             # command line under bash
 sed "s/$/`echo \\\r`/"               # command line under zsh
 sed 's/$/\r/'                        # gsed 3.02.80

 # IN DOS ENVIRONMENT: convert Unix newlines (LF) to DOS format
 sed "s/$//"                          # method 1
 sed -n p                             # method 2

 # IN DOS ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
 # Cannot be done with DOS versions of sed. Use "tr" instead.
 tr -d \r <infile >outfile            # GNU tr version 1.22 or higher

 # delete leading whitespace (spaces, tabs) from front of each line
 # aligns all text flush left
 sed 's/^[ \t]*//'                    # see note on '\t' at end of file

 # delete trailing whitespace (spaces, tabs) from end of each line
 sed 's/[ \t]*$//'                    # see note on '\t' at end of file

 # delete BOTH leading and trailing whitespace from each line
 sed 's/^[ \t]*//;s/[ \t]*$//'

 # insert 5 blank spaces at beginning of each line (make page offset)
 sed 's/^/     /'

 # align all text flush right on a 79-column width
 sed -e :a -e 's/^.\{1,78\}$/ &/;ta'  # set at 78 plus 1 space

 # center all text in the middle of 79-column width. In method 1,
 # spaces at the beginning of the line are significant, and trailing
 # spaces are appended at the end of the line. In method 2, spaces at
 # the beginning of the line are discarded in centering the line, and
 # no trailing spaces appear at the end of lines.
 sed  -e :a -e 's/^.\{1,77\}$/ & /;ta'                     # method 1
 sed  -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/'  # method 2

 # substitute (find and replace) "foo" with "bar" on each line
 sed 's/foo/bar/'             # replaces only 1st instance in a line
 sed 's/foo/bar/4'            # replaces only 4th instance in a line
 sed 's/foo/bar/g'            # replaces ALL instances in a line
 sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # replace the next-to-last case
 sed 's/\(.*\)foo/\1bar/'            # replace only the last case

 # substitute "foo" with "bar" ONLY for lines which contain "baz"
 sed '/baz/s/foo/bar/g'

 # substitute "foo" with "bar" EXCEPT for lines which contain "baz"
 sed '/baz/!s/foo/bar/g'

 # change "scarlet" or "ruby" or "puce" to "red"
 sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'   # most seds
 gsed 's/scarlet\|ruby\|puce/red/g'                # GNU sed only

 # reverse order of lines (emulates "tac")
 # bug/feature in HHsed v1.5 causes blank lines to be deleted
 sed '1!G;h;$!d'               # method 1
 sed -n '1!G;h;$p'             # method 2

 # reverse each character on the line (emulates "rev")
 sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'

 # join pairs of lines side-by-side (like "paste")
 sed '$!N;s/\n/ /'

 # if a line ends with a backslash, append the next line to it
 sed -e :a -e '/\\$/N; s/\\\n//; ta'

 # if a line begins with an equal sign, append it to the previous line
 # and replace the "=" with a single space
 sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'

 # add commas to numeric strings, changing "1234567" to "1,234,567"
 gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta'                     # GNU sed
 sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'  # other seds

 # add commas to numbers with decimal points and minus signs (GNU sed)
 gsed ':a;s/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g;ta'

 # add a blank line every 5 lines (after lines 5, 10, 15, 20, etc.)
 gsed '0~5G'                  # GNU sed only
 sed 'n;n;n;n;G;'             # other seds

SELECTIVE PRINTING OF CERTAIN LINES:

 # print first 10 lines of file (emulates behavior of "head")
 sed 10q

 # print first line of file (emulates "head -1")
 sed q

 # print the last 10 lines of a file (emulates "tail")
 sed -e :a -e '$q;N;11,$D;ba'

 # print the last 2 lines of a file (emulates "tail -2")
 sed '$!N;$!D'

 # print the last line of a file (emulates "tail -1")
 sed '$!d'                    # method 1
 sed -n '$p'                  # method 2

 # print only lines which match regular expression (emulates "grep")
 sed -n '/regexp/p'           # method 1
 sed '/regexp/!d'             # method 2

 # print only lines which do NOT match regexp (emulates "grep -v")
 sed -n '/regexp/!p'          # method 1, corresponds to above
 sed '/regexp/d'              # method 2, simpler syntax

 # print the line immediately before a regexp, but not the line
 # containing the regexp
 sed -n '/regexp/{g;1!p;};h'

 # print the line immediately after a regexp, but not the line
 # containing the regexp
 sed -n '/regexp/{n;p;}'

 # print 1 line of context before and after regexp, with line number
 # indicating where the regexp occurred (similar to "grep -A1 -B1")
 sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

 # grep for AAA and BBB and CCC (in any order)
 sed '/AAA/!d; /BBB/!d; /CCC/!d'

 # grep for AAA and BBB and CCC (in that order)
 sed '/AAA.*BBB.*CCC/!d'

 # grep for AAA or BBB or CCC (emulates "egrep")
 sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d    # most seds
 gsed '/AAA\|BBB\|CCC/!d'                        # GNU sed only

 # print paragraph if it contains AAA (blank lines separate paragraphs)
 # HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below
 sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'

 # print paragraph if it contains AAA and BBB and CCC (in any order)
 sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

 # print paragraph if it contains AAA or BBB or CCC
 sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
 gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d'         # GNU sed only

 # print only lines of 65 characters or longer
 sed -n '/^.\{65\}/p'

 # print only lines of less than 65 characters
 sed -n '/^.\{65\}/!p'        # method 1, corresponds to above
 sed '/^.\{65\}/d'            # method 2, simpler syntax

 # print section of file from regular expression to end of file
 sed -n '/regexp/,$p'

 # print section of file based on line numbers (lines 8-12, inclusive)
 sed -n '8,12p'               # method 1
 sed '8,12!d'                 # method 2

 # print line number 52
 sed -n '52p'                 # method 1
 sed '52!d'                   # method 2
 sed '52q;d'                  # method 3, efficient on large files

 # beginning at line 3, print every 7th line
 gsed -n '3~7p'               # GNU sed only
 sed -n '3,${p;n;n;n;n;n;n;}' # other seds

 # print section of file between two regular expressions (inclusive)
 sed -n '/Iowa/,/Montana/p'             # case sensitive

SELECTIVE DELETION OF CERTAIN LINES:

 # print all of file EXCEPT section between 2 regular expressions
 sed '/Iowa/,/Montana/d'

 # delete duplicate, consecutive lines from a file (emulates "uniq").
 # First line in a set of duplicate lines is kept, rest are deleted.
 sed '$!N; /^\(.*\)\n\1$/!P; D'

 # delete duplicate, nonconsecutive lines from a file. Beware not to
 # overflow the buffer size of the hold space, or else use GNU sed.
 sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'

 # delete the first 10 lines of a file
 sed '1,10d'

 # delete the last line of a file
 sed '$d'

 # delete the last 2 lines of a file
 sed 'N;$!P;$!D;$d'

 # delete the last 10 lines of a file
 sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
 sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2

 # delete every 8th line
 gsed '0~8d'                           # GNU sed only
 sed 'n;n;n;n;n;n;n;d;'                # other seds

 # delete ALL blank lines from a file (same as "grep '.' ")
 sed '/^$/d'                           # method 1
 sed '/./!d'                           # method 2

 # delete all CONSECUTIVE blank lines from file except the first; also
 # deletes all blank lines from top and end of file (emulates "cat -s")
 sed '/./,/^$/!d'          # method 1, allows 0 blanks at top, 1 at EOF
 sed '/^$/N;/\n$/D'        # method 2, allows 1 blank at top, 0 at EOF

 # delete all CONSECUTIVE blank lines from file except the first 2:
 sed '/^$/N;/\n$/N;//D'

 # delete all leading blank lines at top of file
 sed '/./,$!d'

 # delete all trailing blank lines at end of file
 sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'  # works on all seds
 sed -e :a -e '/^\n*$/N;/\n$/ba'        # ditto, except for gsed 3.02*

 # delete the last line of each paragraph
 sed -n '/^$/{p;h;};/./{x;/./p;}'

SPECIAL APPLICATIONS:

 # remove nroff overstrikes (char, backspace) from man pages. The 'echo'
 # command may need an -e switch if you use Unix System V or bash shell.
 sed "s/.`echo \\\b`//g"    # double quotes required for Unix environment
 sed 's/.^H//g'             # in bash/tcsh, press Ctrl-V and then Ctrl-H
 sed 's/.\x08//g'           # hex expression for sed v1.5

 # get Usenet/e-mail message header
 sed '/^$/q'                # deletes everything after first blank line

 # get Usenet/e-mail message body
 sed '1,/^$/d'              # deletes everything up to first blank line

 # get Subject header, but remove initial "Subject: " portion
 sed '/^Subject: */!d; s///;q'

 # get return address header
 sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

 # parse out the address proper. Pulls out the e-mail address by itself
 # from the 1-line return address header (see preceding script)
 sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'

 # add a leading angle bracket and space to each line (quote a message)
 sed 's/^/> /'

 # delete leading angle bracket & space from each line (unquote a message)
 sed 's/^> //'

 # remove most HTML tags (accommodates multiple-line tags)
 sed -e :a -e 's/<[^>]*>//g;/</N;//ba'

 # extract multi-part uuencoded binaries, removing extraneous header
 # info, so that only the uuencoded portion remains. Files passed to
 # sed must be passed in the proper order. Version 1 can be entered
 # from the command line; version 2 can be made into an executable
 # Unix shell script. (Modified from a script by Rahul Dhesi.)
 sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode   # vers. 1
 sed '/^end/,/^begin/d' "$@" | uudecode                    # vers. 2

 # zip up each .TXT file individually, deleting the source file and
 # setting the name of each .ZIP file to the basename of the .TXT file
 # (under DOS: the "dir /b" switch returns bare filenames in all caps).
 echo @echo off >zipup.bat
 dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

TYPICAL USE: Sed takes one or more editing commands and applies all of
them, in sequence, to each line of input. After all the commands have
been applied to the first input line, that line is output and a second
input line is taken for processing, and the cycle repeats. The
preceding examples assume that input comes from the standard input
device (i.e, the console, normally this will be piped input). One or
more filenames can be appended to the command line if the input does
not come from stdin. Output is sent to stdout (the screen). Thus:

 cat filename | sed '10q'        # uses piped input
 sed '10q' filename              # same effect, avoids a useless "cat"
 sed '10q' filename > newfile    # redirects output to disk

For additional syntax instructions, including the way to apply editing
commands from a disk file instead of the command line, consult "sed &
awk, 2nd Edition," by Dale Dougherty and Arnold Robbins (O'Reilly,
1997; http://www.ora.com), "UNIX Text Processing," by Dale Dougherty
and Tim O'Reilly (Hayden Books, 1987) or the tutorials by Mike Arst
distributed in U-SEDIT2.ZIP (many sites). To fully exploit the power
of sed, one must understand "regular expressions." For this, see
"Mastering Regular Expressions" by Jeffrey Friedl (O'Reilly, 1997).
The manual ("man") pages on Unix systems may be helpful (try "man
sed", "man regexp", or the subsection on regular expressions in "man
ed"), but man pages are notoriously difficult. They are not written to
teach sed use or regexps to first-time users, but as a reference text
for those already acquainted with these tools.

QUOTING SYNTAX: The preceding examples use single quotes ('...')
instead of double quotes ("...") to enclose editing commands, since
sed is typically used on a Unix platform. Single quotes prevent the
Unix shell from intrepreting the dollar sign ($) and backquotes
(`...`), which are expanded by the shell if they are enclosed in
double quotes. Users of the "csh" shell and derivatives will also need
to quote the exclamation mark (!) with the backslash (i.e., \!) to
properly run the examples listed above, even within single quotes.
Versions of sed written for DOS invariably require double quotes
("...") instead of single quotes to enclose editing commands.

USE OF '\t' IN SED SCRIPTS: For clarity in documentation, we have used
the expression '\t' to indicate a tab character (0x09) in the scripts.
However, most versions of sed do not recognize the '\t' abbreviation,
so when typing these scripts from the command line, you should press
the TAB key instead. '\t' is supported as a regular expression
metacharacter in awk, perl, and HHsed, sedmod, and GNU sed v3.02.80.

VERSIONS OF SED: Versions of sed do differ, and some slight syntax
variation is to be expected. In particular, most do not support the
use of labels (:name) or branch instructions (b,t) within editing
commands, except at the end of those commands. We have used the syntax
which will be portable to most users of sed, even though the popular
GNU versions of sed allow a more succinct syntax. When the reader sees
a fairly long command such as this:

   sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

it is heartening to know that GNU sed will let you reduce it to:

   sed '/AAA/b;/BBB/b;/CCC/b;d'      # or even
   sed '/AAA\|BBB\|CCC/b;d'

In addition, remember that while many versions of sed accept a command
like "/one/ s/RE1/RE2/", some do NOT allow "/one/! s/RE1/RE2/", which
contains space before the 's'. Omit the space when typing the command.

OPTIMIZING FOR SPEED: If execution speed needs to be increased (due to
large input files or slow processors or hard disks), substitution will
be executed more quickly if the "find" expression is specified before
giving the "s/.../.../" instruction. Thus:

   sed 's/foo/bar/g' filename         # standard replace command
   sed '/foo/ s/foo/bar/g' filename   # executes more quickly
   sed '/foo/ s//bar/g' filename      # shorthand sed syntax

On line selection or deletion in which you only need to output lines
from the first part of the file, a "quit" command (q) in the script
will drastically reduce processing time for large files. Thus:

   sed -n '45,50p' filename           # print line nos. 45-50 of a file
   sed -n '51q;45,50p' filename       # same, but executes much faster

If you have any additional scripts to contribute or if you find errors
in this document, please send e-mail to the compiler. Indicate the
version of sed you used, the operating system it was compiled for, and
the nature of the problem. Various scripts in this file were written
or contributed by:

 Al Aab <af137@freenet.toronto.on.ca>   # "seders" list moderator
 Edgar Allen <era@sky.net>              # various
 Yiorgos Adamopoulos <adamo@softlab.ece.ntua.gr>
 Dale Dougherty <dale@songline.com>     # author of "sed & awk"
 Carlos Duarte <cdua@algos.inesc.pt>    # author of "do it with sed"
 Eric Pement <pemente@northpark.edu>    # author of this document
 Ken Pizzini <ken@halcyon.com>          # author of GNU sed v3.02
 S.G. Ravenhall <stew.ravenhall@totalise.co.uk> # great de-html script
 Greg Ubben <gsu@romulus.ncsc.mil>      # many contributions & much help

作者: admin 分类: Shell 标签:

Mysql备份脚本 带压缩 显示压缩率 日志

2008年3月21日

#!/bin/sh
#
# Copyright (C), 2007 bug All Rights Reserved

# Title       : Database Backup Script
# Author      : BUG
# File        : db_bak.sh
# Version     : 1.1.0
# Date        : 2008-03-21
# Email       : efbbb27115@homtail.com
# License     : General Public License (GPL) v2
# Description : Database Backup Script
#

initial() {

    echo -en "\33[2J"

    echo -en "\33[0;0H"

    echo -en "\33[32m"

    echo "------------------------------------------------------------"

    echo "---                Database Backup Script                ---"

    echo "------------------------------------------------------------"

    echo -en "\33[37m"

    stty -echo

    umask 077

    mysqln=`echo 'show databases;' | /usr/local/mysql/bin/mysql -psjldafhkg | sed -n '3,$p'`

    mysqlu="root"

    mysqlp="********"

    binpath="/usr/local/mysql/bin"

    dstpath="/pri/bak/sql_bak/"

    runuser=`ps aux | grep $$ | sed -n "1p" | awk '{ print $1 }'`

    mkdir -p $dstpath/`date +%y%m%d`

    exec 3>>$dstpath/`date +%y%m%d`/db_bak.log

}initialecho -e "\n[`date +%y/%m/%d\ %H:%M:%S`] Database Backup Script start by $runuser PID:$$" >&3if [ -f "$dstpath/`date +%y%m%d`/lock" ]

then

    echo -e "\33[33mIt's has completed by `cat $dstpath/\`date +%y%m%d\`/lock`!!!\33[37m"

    echo "[`date +%y/%m/%d\ %H:%M:%S`] It's has completed by `cat $dstpath/\`date +%y%m%d\`/lock`!!!" >&3

else

    echo -e "Database\tExport\tCompress\tSql\tTgz\tRate"

    echo -e "\33[32m------------------------------------------------------------\33[37m"

    cd $dstpath/`date +%y%m%d`

    for db in $mysqln

    do

    echo -n "$db"

    $binpath/mysqldump --opt -u$mysqlu -p$mysqlp $db > $dstpath/`date +%y%m%d`/$db.sql 2> /dev/null

    RETVAL1=$?

    if [ $RETVAL1 -eq 0 ]

    then

    sqlsize=`du -k $db.sql | cut -f1`

    echo -n "[`date +%y/%m/%d\ %H:%M:%S`]" >&3

    echo -n "$db" | awk '{printf " %-17s", $1}' >&3

    echo -n "OK  " >&3

    echo -en "\r\t\t  \33[32mOK\33[37m\t"

    tar -czvf $db.tgz $db.sql > /dev/null 2>&1

        RETVAL2=$?

        if [ $RETVAL2 -eq 0 ]

        then

        tgzsize=`du -k $db.tgz | cut -f1`

        echo "OK" >&3

        rm -f $dstpath/`date +%y%m%d`/$db.sql

        echo -en "   \33[32mOK\33[37m"

        echo -en "\33[33m"

        echo -en "$sqlsize" | awk '{printf "%12dKB", $1}'

        echo -en "$tgzsize" | awk '{printf "%6sKB", $1}'

        echo "$sqlsize $tgzsize" | awk '{printf "%8.0f%",$2/$1*100}'

        echo -e "\33[37m"

        else

        echo "Compress fail return $RETVAL2" >&3

        echo -e "  \33[31mfail\33[37m"

        fi

    else

    echo -n "[`date +%y/%m/%d\ %H:%M:%S`]" >&3

    echo -n "$db" | awk '{printf " %-17s ", $1}' >&3

    echo "Export fail return $RETVAL1" >&3

    echo -en "\r\t\t   \33[31mfail\33[37m"

    fi

    done

    echo "`date +%H:%M:%S`">$dstpath/`date +%y%m%d`/lock

fi

作者: admin 分类: MySQL, Shell 标签:

find命令详解

2008年1月31日

功能说明:查找文件或目录。

语  法:find [目录...][-amin <分钟>][-anewer <参考文件或目录>][-atime <24小时数>][-cmin <分钟>][-cnewer <参考文件或目录>][-ctime <24小时数>][-daystart][-depyh][-empty][-exec <执行指令>][-false][-fls <列表文件>][-follow][-fprint <列表文件>][-fprint0 <列表文件>][-fprintf <列表文件><输出格式>][-fstype <文件系统类型>][-gid <群组识别码>][-group <群组名称>][-help][-ilname <范本样式>][-iname <范本样式>][-inum <inode编号>][-ipath <范本样式>][-iregex <范本样式>][-links <连接数目>][-lname <范本样式>][-ls][-maxdepth <目录层级>][-mindepth <目录层级>][-mmin <分钟>][-mount]
[-mtime <24小时数>][-name <范本样式>][-newer <参考文件或目录>][-nogroup][noleaf] [-nouser][-ok <执行指令>][-path <范本样式>][-perm <权限数值>][-print][-print0][-printf <输出格式>][-prune][-regex <范本样式>][-size <文件大小>][-true][-type <文件类型>][-uid <用户识别码>][-used <日数>][-user <拥有者名称>][-version][-xdev][-xtype <文件类型>]

补充说明:find指令用于查找符合条件的文件。任何位于参数之前的字符串都将被视为欲查找的目录。

参  数:
 -amin<分钟>  查找在指定时间曾被存取过的文件或目录,单位以分钟计算。
 -anewer<参考文件或目录>  查找其存取时间较指定文件或目录的存取时间更接近现在的文件或目录。
 -atime<24小时数>  查找在指定时间曾被存取过的文件或目录,单位以24小时计算。
 -cmin<分钟>  查找在指定时间之时被更改的文件或目录。
 -cnewer<参考文件或目录>  查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录。
 -ctime<24小时数>  查找在指定时间之时被更改的文件或目录,单位以24小时计算。
 -daystart  从本日开始计算时间。
 -depth  从指定目录下最深层的子目录开始查找。
 -expty  寻找文件大小为0 Byte的文件,或目录下没有任何子目录或文件的空目录。
 -exec<执行指令>  假设find指令的回传值为True,就执行该指令。
 -false  将find指令的回传值皆设为False。
 -fls<列表文件>  此参数的效果和指定"-ls"参数类似,但会把结果保存为指定的列表文件。
 -follow  排除符号连接。
 -fprint<列表文件>  此参数的效果和指定"-print"参数类似,但会把结果保存成指定的列表文件。
 -fprint0<列表文件>  此参数的效果和指定"-print0"参数类似,但会把结果保存成指定的列表文件。
 -fprintf<列表文件><输出格式>  此参数的效果和指定"-printf"参数类似,但会把结果保存成指定的列表文件。
 -fstype<文件系统类型>  只寻找该文件系统类型下的文件或目录。
 -gid<群组识别码>  查找符合指定之群组识别码的文件或目录。
 -group<群组名称>  查找符合指定之群组名称的文件或目录。
 -help或--help  在线帮助。
 -ilname<范本样式>  此参数的效果和指定"-lname"参数类似,但忽略字符大小写的差别。
 -iname<范本样式>  此参数的效果和指定"-name"参数类似,但忽略字符大小写的差别。
 -inum<inode编号>  查找符合指定的inode编号的文件或目录。
 -ipath<范本样式>  此参数的效果和指定"-ipath"参数类似,但忽略字符大小写的差别。
 -iregex<范本样式>  此参数的效果和指定"-regexe"参数类似,但忽略字符大小写的差别。
 -links<连接数目>  查找符合指定的硬连接数目的文件或目录。
 -iname<范本样式>  指定字符串作为寻找符号连接的范本样式。
 -ls  假设find指令的回传值为True,就将文件或目录名称列出到标准输出。
 -maxdepth<目录层级>  设置最大目录层级。
 -mindepth<目录层级>  设置最小目录层级。
 -mmin<分钟>  查找在指定时间曾被更改过的文件或目录,单位以分钟计算。
 -mount  此参数的效果和指定"-xdev"相同。
 -mtime<24小时数>  查找在指定时间曾被更改过的文件或目录,单位以24小时计算。
 -name<范本样式>  指定字符串作为寻找文件或目录的范本样式。
 -newer<参考文件或目录>  查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录。
 -nogroup  找出不属于本地主机群组识别码的文件或目录。
 -noleaf  不去考虑目录至少需拥有两个硬连接存在。
 -nouser  找出不属于本地主机用户识别码的文件或目录。
 -ok<执行指令>  此参数的效果和指定"-exec"参数类似,但在执行指令之前会先询问用户,若回答"y"或"Y",则放弃执行指令。
 -path<范本样式>  指定字符串作为寻找目录的范本样式。
 -perm<权限数值>  查找符合指定的权限数值的文件或目录。
 -print  假设find指令的回传值为True,就将文件或目录名称列出到标准输出。格式为每列一个名称,每个名称之前皆有"./"字符串。
 -print0  假设find指令的回传值为True,就将文件或目录名称列出到标准输出。格式为全部的名称皆在同一行。
 -printf<输出格式>  假设find指令的回传值为True,就将文件或目录名称列出到标准输出。格式可以自行指定。
 -prune  不寻找字符串作为寻找文件或目录的范本样式。
 -regex<范本样式>  指定字符串作为寻找文件或目录的范本样式。
 -size<文件大小>  查找符合指定的文件大小的文件。
 -true  将find指令的回传值皆设为True。
 -typ<文件类型>  只寻找符合指定的文件类型的文件。
 -uid<用户识别码>  查找符合指定的用户识别码的文件或目录。
 -used<日数>  查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算。
 -user<拥有者名称>  查找符合指定的拥有者名称的文件或目录。
 -version或--version  显示版本信息。
 -xdev  将范围局限在先行的文件系统中。
 -xtype<文件类型>  此参数的效果和指定"-type"参数类似,差别在于它针对符号连接检查

作者: admin 分类: Shell 标签:

Bash中对变量的操作

2008年1月26日

1.条件变量替换:
  Bash Shell可以进行变量的条件替换,既只有某种条件发生时才进行替换,替换
条件放在{}中.
  (1) ${value:-word}
      当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值.
  (2) ${value:=word}
      与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将
      word赋值给value
  (3) ${value:?message}
      若变量以赋值的话,正常替换.否则将消息message送到标准错误输出(若
      此替换出现在Shell程序中,那么该程序将终止运行)
  (4) ${value:+word}
      若变量以赋值的话,其值才用word替换,否则不进行任何替换
  (5) ${value:offset}
      ${value:offset:length}
      从变量中提取子串,这里offset和length可以是算术表达式.
  (6) ${#value}
      变量的字符个数
  (7) ${value#pattern}
      ${value##pattern}
      去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配
      #与##的区别在于一个是最短匹配模式,一个是最长匹配模式.
  (8) ${value%pattern}
      ${value%%pattern}
      于(7)类似,只是是从value的尾部于pattern相匹配,%与%%的区别与#与##一样
  (9) ${value/pattern/string}
      ${value//pattern/string}
      进行变量内容的替换,把与pattern匹配的部分替换为string的内容,/与//的区
      别与上同

注意:上述条件变量替换中,除(2)外,其余均不影响变量本身的值
2.变量的算术运算
  在Bash Shell中,只能进行两个整数间的运算,其结果仍为整数.要进行算术
运算,需要使用let命令,语法为:
  let expr
  expr是一个包含项和操作符的表达式,项可以是一个变量或是一个整数常数,
当使用整数常数时,其默认为十进制整数,用户可以用radio#number来指定其它
形式的整数,其中radio定义了整数是几进制表示的,number是该整数的值.若
radio>10,那么数字字符可从0-9和A-Z.
  在表达式中支持的操作符及其含义为:
  +,-,*,/,%     加,减,乘,除,取模
  >>,<<,&,^,|   左移,右移,位与,位异或,位或
  ?:            三元运算符.与C语言中的定义一致
  ~             取补码
  !,>=,<=,>,<,==,!=,&&,||
  =,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
  表达式式中也可以使用括号.括号或运算优先级的定义与一般计算机语言中的
相同.
  let命令具有返回值.当计算结果(若有多个表达式时,以最后一个为准)为0时,
返回值为1,否则为0.
  当表达式中含有shell的特殊字符(如|)时,需要用引用符('或")将其引用起来.
  使用let时还需要注意的时,对于let x+y这样的式子,shell虽然计算了x+y的值
但却将结果丢弃,若不想这样,可以使用let sum=x+y将x+y的结果保存在变量sum中
  另外还可以使用((和))操作符取代let命令,而且这样的话,还可以省去对算术
表达式的引用,如果想返回表达式的值,则需用$(())的格式.

作者: admin 分类: Shell 标签: