slackware 配置

My computer's hardware:
cpu: pentium4 2.4G
memory: 256+512/M
graphic card: nVidia GForce MX 400
harddisk:sumsung40 + 40G

slackware version: 12.1
other os: windowsXP

1, After all softwares contained in CD, I install the driver for the nvidia card :
Ctrl + Alt + backspace : shut the kde,
then ,
#cd ~ ; ./NVIDIA-Linux-x86-96.43.11-pkg1.run
when the installation of the driver completed, #startx.

then make the mouse's wheel work:

#vim /etc/X11/xorg.conf
find the

Section "InputDevice"
# generated from default
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/psaux"
Option "Emulate3Buttons" "no"
Option "ZAxisMapping" "4 5"
EndSection

set the "Option protocol" as IMPS/2
Option "Protocol" "IMPS/2"




2, Download the wenquanyi fonts and install it following the install instruction in the directory extracted from the tarball.

3, SCIM configuration: #vim ~/.xinitrc and add the following lines:

scim -d &
export LANG=en_US.UTF-8
export LC_CTYPE=zh_CN.UTF-8
export XMODIFIERS=@im=SCIM
export GTK_IM_MODULE=SCIM
export QT_IM_MODULE=SCIM

before the "startkde"

4, wget :
#vim /etc/wgetrc
uncomment the
“http_proxy=....” and “ftp_proxy=...”
input your proxy behind the "="
then turn the "use_proxy=off" on.

5,my simple .bashrc
#vim ~/.bashrc

PS1 ='\[\033[1;33;44m\]\u@\h:\w\$\[\033[0m\]'

alias ls="/bin/ls --color=auto --classify"
alias ll="ls -l"
alias all="ls -all"
alias g++opencv=g++ `pkg-config opencv --libs --cflags opencv`

reboot my computer

Readmore »»

端口的概念(转载)

可以这样说:端口便是计算机与外部通信的途径,没有它,计算机便又聋又哑。
在网络技术中,端口(Port)有好几种意思。集线器、交换机、路由 器的端口指的是连接其他网络设备的接口,如RJ-45端口、Serial端口等。我们 这里所指的端口不是指物理意义上的端口,而是特指TCP/IP协议中的端口,是逻辑意义上的端口。


那么TCP/IP协议中的端口指的是什么呢?如果把IP地址比作一间房子 ,端口就是出入这间房子的门。真正的房子只有几个门,但是一个IP地址的端口 可以有65536个之多!端口是通过端口号来标记的,端口号只有整数,范围是从0 到65535。

端口有什么用呢?我们知道,一台拥有IP地址的主机可以提供许多服务,比如Web服务、ftp服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区分不同的服务的。

需要注意的是,端口并不是一一对应的。比如你的电脑作为客户机访 问一台WWW服务器时,WWW服务器使用“80”端口与你的电脑通信,但你的电脑则 可能使用“3457”这样的端口,如图1所示。
按对应的协议类型,端口有两种:TCP端口和UDP端口。由于TCP和UDP 两个协议是独立的,因此各自的端口号也相互独立,比如TCP有235端口,UDP也 可以有235端口,两者并不冲突。

端口是怎样分配的

与IP地址一样,端口号也不是随意使用的,而是按照一定的规定进行 分配。端口的分类标准有好几种,我们这里不做详细讲解,只介绍一下周知端口和动态端口。

1.周知端口(Well Known Ports)

周知端口是众所周知的端口号,范围从0到1023,其中80端口分配给W WW服务,21端口分配给ftp服务等。我们在IE的地址栏里输入一个网址的时候( 比如www.cce.com.cn)是不必指定端口号的,因为在默认情况下WWW服务的端口 号是“80”。

网络服务是可以使用其他端口号的,如果不是默认的端口号则应该在 地址栏上指定端口号,方法是在地址后面加上冒号“:”(半角),再加上端口号。比如使用“8080”作为WWW服务的端口,则需要在地址栏里输入“www.gonet8.com gonet8.com:8080”。

但是有些系统协议使用固定的端口号,它是不能被改变的,比如139 端口专门用于NetBIOS与TCP/IP之间的通信,不能手动改变。

2.动态端口(Dynamic Ports)

动态端口的范围是从1024到65535。之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。动态分配是指当一个系统进程或应用 程序进程需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配一个供它使用。当这个进程关闭时,同时也就释放了所占用的端口号。

Readmore »»

Master the Linux bash command line with these 10 shortcuts

If you've ever typed a command at the Linux shell prompt, you've probably already used bash—after all, it's the default command shell on most modern GNU/Linux distributions. The bash shell is the primary interface to the Linux operating system—it accepts, interprets and executes your commands, and provides you with the building blocks for shell scripting and automated task execution.

bash's unassuming exterior hides some very powerful tools and shortcuts. If you're a heavy user of the command line, these can save you a fair bit of typing. This document outlines ten of the most useful tools:



1. Easily recall previous commands

bash keeps track of the commands you execute in a history buffer, and allows you to recall previous commands by cycling through them with the Up and Down cursor keys. For even faster recall, "speed search" previously-executed commands by typing the first few letters of the command followed by the key combination Ctrl-R; bash will then scan the command history for matching commands and display them on the console. Type Ctrl-R repeatedly to cycle through the entire list of matching commands.
2. Use command aliases

If you always run a command with the same set of options, you can have bash create an alias for it. This alias will incorporate the required options, so that you don't need to remember them or manually type them every time. For example, if you always run ls with the -l option to obtain a detailed directory listing, you can use this command:
bash> alias ls='ls -l'

To create an alias that automatically includes the -l option. Once this alias has been created, typing ls at the bash prompt will invoke the alias and produce the ls -l output.

You can obtain a list of available aliases by invoking alias without any arguments, and you can delete an alias with unalias.
3. Use filename auto-completion

bash supports filename auto-completion at the command prompt. To use this feature, type the first few letters of the file name, followed by Tab. bash will scan the current directory, as well as all other directories in the search path, for matches to that name. If a single match is found, bash will automatically complete the filename for you. If multiple matches are found, you will be prompted to choose one.
4. Use key shortcuts to efficiently edit the command line

bash supports a number of keyboard shortcuts for command-line navigation and editing. The Ctrl-A key shortcut moves the cursor to the beginning of the command line, while the Ctrl-E shortcut moves the cursor to the end of the command line. The Ctrl-W shortcut deletes the word immediately before the cursor, while the Ctrl-K shortcut deletes everything immediately after the cursor. You can undo a deletion with Ctrl-Y.
5. Get automatic notification of new mail

You can configure bash to automatically notify you of new mail, by setting the $MAILPATH variable to point to your local mail spool. For example, the command:
bash> MAILPATH='/var/spool/mail/john'
bash> export MAILPATH

Causes bash to print a notification on john's console every time a new message is appended to john's mail spool.
6. Run tasks in the background

bash lets you run one or more tasks in the background, and selectively suspend or resume any of the current tasks (or "jobs"). To run a task in the background, add an ampersand (&) to the end of its command line. Here's an example:
bash> tail -f /var/log/messages &
[1] 614

Each task back-grounded in this manner in assigned a job ID, which is printed to the console. A task can be brought back to the foreground with the command fgjobnumber, where jobnumber is the job ID of the task you wish to bring to the foreground. Here's an example:
bash> fg 1

A list of active jobs can be obtained at any time by typing jobs at the bash prompt.
7. Quickly jump to frequently-used directories

You probably already know that the $PATH variable lists bash's "search path" - the directories it will search when it can't find the requested file in the current directory. However, bash also supports the $CDPATH variable, which lists the directories the cd command will look in when attempting to change directories. To use this feature, assign a directory list to the $CDPATH variable, as shown in the example below:
bash> CDPATH='.:~:/usr/local/apache/htdocs:/disk1/backups'
bash> export CDPATH

Now, whenever you use the cd command, bash will check all the directories in the $CDPATH list for matches to the directory name.
8. Perform calculations

bash can perform simple arithmetic operations at the command prompt. To use this feature, simply type in the arithmetic expression you wish to evaluate at the prompt within double parentheses, as illustrated below. bash will attempt to perform the calculation and return the answer.
bash> echo $((16/2))
8
9. Customize the shell prompt

You can customize the bash shell prompt to display—among other things—the current user name and host name, the current time, the load average and/or the current working directory. To do this, alter the $PS1 variable, as below:
bash> PS1='\u@\h:\w \@> '
bash> export PS1
root@medusa:/tmp 03:01 PM>

This will display the name of the currently logged-in user, the host name, the current working directory and the current time at the shell prompt. You can obtain a list of symbols understood by bash from its manual page.
10. Get context-specific help

bash comes with help for all built-in commands. To see a list of all built-in commands, type help. To obtain help on a specific command, type help command, where command is the command you need help on. Here's an example:
bash> help alias
...some help text...

Obviously, you can obtain detailed help on the bash shell by typing man bash at your command prompt at any time.

Readmore »»

bash技巧:提示行魔术

bash技巧:提示行魔术 (PS1环境变量)
作者:
Daniel Robbins
Gentoo Technologies 公司总载兼首席执行官

原文地址:http://www.linuxsir.org/bbs/showthread.php?threadid=20558


如果您很容易使 shell 提示行变得色彩绚烂斓且带有更多信息,为什么还要坚持用单调的标准 shell 提示行呢?在这篇技巧中,Daniel Robbins 将说明如何获得符合您的意愿的 shell 提示行,并会说明如何动态更新 X 终端的标题栏。

作为 Linux/UNIX 人,我们有很长的时间是在 shell 中工作,并且在许多情况下,下面这一行就是始终盯着我们的那个提示行:
bash-2.04$
如果您恰巧是超级用户 (root),您就有权使用下面这个美丽的标示“身份”的提示行版本:
bash-2.04#
这些提示行并不是十分漂亮。这也就难怪几种 Linux 版本对默认提示行进行了升级,在其中增加了颜色和更多的信息。但是,即便您恰好有一个本身带有很好的彩色提示行的新式版本,它也不可能是完美无缺的。您或许希望在提示行中增加或更改几种颜色,或者增加(或删除)一些信息。从头开始设计属于您自己的彩色的、经过装饰的提示行并不难。
提示行基础
在 bash 下,可以通过更改 PS1 环境变量的值来设置提示行,如下所示:
$ export PS1="> "
>
更改会立即生效,通过将 "export" 定义放在您的 ~/.bashrc 文件中可将这种更改固定下来。只要您愿意,PS1 可以包含任意数量的纯文本:
$ export PS1="This is my super prompt > "
This is my super prompt >
尽管这很有趣,但在提示行中包含大量静态文本并不是特别有用。大多数定制的提示行包含诸如用户名、工作目录或主机名之类的信息。这些花絮信息可以帮助您在 shell 世界中遨游。例如,下面的提示行将显示您的用户名和主机名:
$ export PS1="\u@\H > "
drobbins@freebox >
这个提示行对于那些以多个不同名称的帐户登录多台机器的人尤为有用,因为它可以提醒您:您目前在哪台机器上操作,拥有什么权限。

在上面的示例中,我们使用了专用的用反斜杠转义的字符序列,藉此通知 bash 将用户名和主机名插入提示行中,当这些转义字符序列出现在 PS1 变量中时,bash 就会用特定的值替换它们。我们使用了序列 "\u"(表示用户名)和 "\H"(表示主机名的第一部分)。下面是 bash 可识别的全部专用序列的完整列表(您可以在 bash man page 的 "PROMPTING" 部分找到这个列表):
序列 说明
\a ASCII 响铃字符(也可以键入 \007)
\d "Wed Sep 06" 格式的日期
\e ASCII 转义字符(也可以键入 \033)
\h 主机名的第一部分(如 "mybox")
\H 主机的全称(如 "mybox.mydomain.com")
\j 在此shell中通过按 ^Z 挂起的进程数
\l 此 shell 的终端设备名(如 "ttyp4")
\n 换行符
\r 回车符
\s shell 的名称(如 "bash")
\t 24 小时制时间(如 "23:01:01")
\T 12 小时制时间(如 "11:01:01")
\@ 带有 am/pm 的 12 小时制时间
\u 用户名
\v bash 的版本(如 2.04)
\V Bash 版本(包括补丁级别)
\w 当前工作目录(如 "/home/drobbins")
\W 当前工作目录的“基名 (basename)”(如 "drobbins")
\! 当前命令在历史缓冲区中的位置
\# 命令编号(只要您键入内容,它就会在每次提示时累加)
\$ 如果您不是超级用户 (root),则插入一个 "$";如果您是超级用户,则显示一个 "#"
\xxx 插入一个用三位数 xxx(用零代替未使用的数字,如 "\007")表示的 ASCII 字符
\\ 反斜杠
\[ 这个序列应该出现在不移动光标的字符序列(如颜色转义序列)之前。它使 bash 能够正确计算自动换行。
\] 这个序列应该出现在非打印字符序列之后。
这样,您已经知道了 bash 中用反斜杠转义的全部专用序列。请稍微演练一下这些序列,以对它们的工作方式获得一些感性认识。在您做了一些测试之后,下面开始添加颜色。
彩色化
添加颜色相当容易;第一步是设计不带颜色的提示行。然后,我们所要做的只是添加终端(而不是 bash)可识别的专用转义序列,以使它以彩色显示文本的某些部分。标准 Linux 终端和 X 终端允许您设置前景(文字)颜色和背景颜色,如果需要,还可以启用 "bold" 字符。有八种颜色可供我们选择。
颜色是通过在 PS1 中添加专用序列来选择的 -- 基本上是夹在 "\e["(转义开方括号)和 "m" 之间数字值。如果指定一个以上的数字代码,则用分号将它们分开。下面是一个颜色代码示例:
"\e[0m"
如果将数字代码指定为零,则它就会通知终端将前景、背景和加粗设置重置为它们的默认值。您可能会在在提示行结束时使用这个代码,以使您键入的文字成为非彩色的。现在,让我们看一下这些颜色代码。请注意下面的抓屏结果:
颜色表
要使用这个表,首先请查找您要使用的颜色,然后查找对应的前景编号 (30-37) 和背景编号 (40-47)。例如,如果您喜欢黑底绿字,则可将编号分别设为 32 和 40。然后打开您的提示行定义并在其中添加适当的颜色代码。下面的定义:
export PS1="\w> "
变为:
export PS1="\e[32;40m\w> "
到现在为止,提示行尽管已经很不错了,但仍不太完美。在 bash 显示出工作目录以后,我们需要使用 "\e[0m" 序列将颜色重新设置为正常值。
export PS1="\e[32;40m\w> \e[0m"
这个定义将显示一个漂亮的绿色提示行,但我们仍需要做一些扫尾工作。我们不需要包括 "40" 这个背景颜色设置,因为它将背景设置为黑色,而黑色是默认颜色。此外,绿色还很暗;我们通过添加一个 "1" 颜色代码来修正这个问题,这将启用更亮的加粗文字。除了这个修改之外,我们还需要将全部非打印字符用专用的 bash 转义序列 "\[" 和 "\]" 括起来。这两个序列通知 bash,被括起来的字符不占用行上的任何空间,这样就使自动换行能够继续正常工作。没有这两个转义序列,尽管您有了一个非常漂亮的提示行,但是如果您键入的命令恰好到达终端的最右端,就会造成显示混乱。下面是我们最终的提示行:
export PS1="\[\e[32;1m\]\w> \[\e[0m\]"
别担心在同一个提示行中使用几种颜色,就像下面这样:
export PS1="\[\e[36;1m\]\u@\[\e[32;1m\]\H> \[\e[0m\]"
Xterm 中的乐趣
我已说明了如何在提示行中添加信息和颜色,但您还可以更进一步。您可以通过在提示行中添加专用代码来使 X 终端(如 rxvt 或 aterm)的标题栏得到动态更新。您所要做的只是将下面的序列添加到您的 PS1 提示行中:
"\e]2;titlebar\a"
只须用您希望其出现在 xterm 标题栏中的文字替换子串 "titlebar" 即可,现在已经一切就绪了!不必使用静态文字;您可以将 bash 转义序列插入标题栏中。请查看下面这个示例,它将用户名、主机名和当前工作目录显示在标题栏中,并定义了一个简短、明亮的绿色提示行:
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] "
这就是我在上面的抓屏结果中所用的那个提示行。我喜欢这个提示行,因为它将全部信息显示在标题栏上,而不是显示在终端上,终端对一行可以显示多少字符有限制。顺便提一句,确保用 "\[" 和 "\]" 将您的标题栏序列括起来(因为就终端而言,这个序列是非打印序列)。将大量信息放在标题栏中的问题是,如果您使用非图形终端(如系统控制台),则看不到这些信息。为了解决这个问题,可以在您的 .bashrc 中添加以下几行:
if [ "$TERM" = "linux" ]
then
#we're on the system console or maybe telnetting in
export PS1="\[\e[32;1m\]\u@\H > \[\e[0m\]"
else
#we're not on the console, assume an xterm
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\] "
fi
这个 bash 条件语句将根据当前的终端设置动态设置提示行。为了获得一致性,您一定希望配置您的 ~/.bash_profile,以便它在启动时搜索 (source) 您的 ~/.bashrc。确保您的 ~/.bash_profile 文件中有以下这样一行:
source ~/.bashrc
这样,无论您开启一个登录 shell 还是一个非登录 shell,都会获得同样的提示行。
好了,您已掌握了提示行魔术。现在尽情享受一下,制作一个漂亮的彩色提示行吧


Readmore »»

Linux下Matlab后台运行程序


我的电脑是一台实验室的dell服务器,linux用的是slackware12.1,matlab的版本是7.0.0
要在后台运行matlab,只需要执行:
matlab -nodisplay -r "your function('*' '*');quit"
这条指令包含了退出命令。'*'代表参数。

Readmore »»

What is tty !

终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备。tty是Teletype的缩写。Teletype是最早出现的一种终端设备,很象电传打字机(或者说就是?),是由Teletype公司生产的。在Linux系统的设备特殊文件目录/dev/下,终端特殊设备文件一般有以下几种:

1.串行端口终端(/dev/ttySn)E>
串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。有段时间这些串行端口设备通常被称为终端设备,因为那时它的最大用途就是用来连接终端。这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev /ttyS1)等,设备号分别是(4,0)、(4,1)等,分别对应于DOS系统下的COM1、COM2等。若要向一个端口发送数据,可以在命令行上把标准输出重定向到这些特殊文件名上即可。例如,在命令行提示符下键入:echo test > /dev/ttyS1会把单词”test”发送到连接在ttyS1(COM2)端口的设备上。0(\#

2.伪终端(/dev/pty/)3k
伪终端(Pseudo Terminal)是成对的逻辑终端设备,例如/dev/ptyp3和/dev/ttyp3(或着在设备文件系统中分别是/dev/pty/m3和 /dev/pty/s3)。它们与实际物理设备并不直接相关。如果一个程序把ttyp3看作是一个串行端口设备,则它对该端口的读/写操作会反映在该逻辑终端设备对的另一个上面(ptyp3)。而ptyp3则是另一个程序用于读写操作的逻辑设备。这样,两个程序就可以通过这种逻辑设备进行互相交流,而其中一个使用ttyp3的程序则认为自己正在与一个串行端口进行通信。这很象是逻辑设备对之间的管道操作。`]oc#b
对于ttyp3(s3),任何设计成使用一个串行端口设备的程序都可以使用该逻辑设备。但对于使用ptyp3的程序,则需要专门设计来使用ptyp3(m3)逻辑设备。dVwpk
例如,如果某人在网上使用telnet程序连接到你的计算机上,则telnet程序就可能会开始连接到设备ptyp2(m2)上(一个伪终端端口上)。此时一个getty程序就应该运行在对应的ttyp2(s2)端口上。当telnet从远端获取了一个字符时,该字符就会通过m2、s2传递给getty程序,而getty程序就会通过s2、m2和telnet程序往网络上返回”login:”字符串信息。这样,登录程序与telnet程序就通过“伪终端” 进行通信。通过使用适当的软件,就可以把两个甚至多个伪终端设备连接到同一个物理串行端口上。#oih!
在使用设备文件系统(device filesystem)之前,为了得到大量的伪终端设备特殊文件,使用了比较复杂的文件名命名方式。因为只存在16个ttyp(ttyp0—ttypf)的设备文件,为了得到更多的逻辑设备对,就使用了象q、r、s等字符来代替p。例如,ttys8和ptys8就是一个伪终端设备对。不过这种命名方式目前仍然在于RedHat等Linux系统中使用着。-W{m1S
但Linux系统上的Unix98并不使用上述方法,而使用了”pty master”方式,例如/dev/ptm3。它的对应端则会被自动地创建成/dev/pts/3。这样就可以在需要时提供一个pty伪终端。目录 /dev/pts是一个类型为devpts的文件系统,并且可以在被加载文件系统列表中看到。虽然“文件”/dev/pts/3看上去是设备文件系统中的一项,但其实它完全是一种不同的文件系统。f
3.控制终端(/dev/tty)_+`
如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty就是当前进程控制终端的设备特殊文件。可以使用命令”ps –ax”来查看进程与哪个控制终端相连。对于你登录的shell,/dev/tty就是你使用的终端,设备号是(5,0)。使用命令”tty”可以查看它具体对应哪个实际终端设备。/dev/tty有些类似于到实际所使用终端设备的一个联接或别名。Uzlz
4.控制台(/dev/ttyn, /dev/console)`k
在Linux系统中,计算机显示器通常被称为控制台终端或控制台(Console)。它仿真了类型为Linux的一种终端(TERM=Linux),并且有一些设备特殊文件与之相关联:tty0、tty1、tty2等。当你在控制台上登录时,使用的是tty1。使用Alt+[F1—F6]组合键时,我们就可以切换到tty2、tty3等上面去。tty1 –tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,Linux系统所产生的信息都会发送到该终端上。因此不管当前我们正在使用哪个虚拟终端,系统信息都会发送到我们的屏幕上。C}$k]\
你可以登录到不同的虚拟终端上去,因而可以让系统同时有几个不同的会话存在。但只有系统或超级用户root可以向/dev/tty0进行写操作,而且有时/dev/console会连接至/dev/tty0或/dev/tty1上。Ry
5.其它类型WW
Linux系统中还针对很多不同的字符设备建有很多其它种类的终端设备特殊文件。例如针对ISDN设备的/dev/ttyIn终端设备等。这里不再赘述

Readmore »»

堆和栈的区别 (转贴)

堆和栈的区别
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。

二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}


二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。


2.2
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。

2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结 构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是 一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。


2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

2.5堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

2.6存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。


2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

Readmore »»

Linux终端输出颜色控制

格式: echo "\033[字背景颜色;字体颜色m字符串\033[0m"
例如: echo "\033[41;36m something here \033[0m"
其中41的位置代表底色, 36的位置是代表字的颜色
那些ascii code 是对颜色调用的始末.
\033[ ; m …… \033[0m
字背景颜色范围:40----49
40:黑
41:深红
42:绿

43:黄色
44:蓝色
45:紫色
46:深绿
47:白色
字颜色:30-----------39
30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色

===========ANSI控制码的说明=============
\33[0m 关闭所有属性
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m -- \33[37m 设置前景色
\33[40m -- \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标

我写的一个例程:
#include "stdio.h"

int main(void)
{
int color;
for (color = 0; color < 20; color++)
{
printf("\x1b[1;4;%dmThe color of this line is %d, %s!\x1b[0m\n", 30+color, 30+color, "ha ha");
}
}

Readmore »»

Linux添加环境变量与GCC编译器添加INCLUDE与LIB环境变量

对所有用户有效在/etc/profile增加以下内容。只对当前用户有效在Home目录下的
.bashrc或.bash_profile里增加下面的内容:
(注意:等号前面不要加空格,否则可能出现 command not found)

#在PATH中找到可执行文件程序的路径。
export PATH =$PATH:$HOME/bin

#gcc找到头文件的路径
C_INCLUDE_PATH=/usr/include/libxml2:/MyLib
export C_INCLUDE_PATH

#g++找到头文件的路径
CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/libxml2:/MyLib
export CPLUS_INCLUDE_PATH

#找到动态链接库的路径
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/MyLib
export LD_LIBRARY_PATH

#找到静态库的路径
LIBRARY_PATH=$LIBRARY_PATH:/MyLib
export LIBRARY_PATH


库文件在连接(静态库和共享 库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到 库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:

在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。

在 /etc/ld.so.conf 文件中添加库的搜索路径。

将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择

添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:

/usr/X11R6/lib

/usr/local/lib

/opt/lib

需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库) 的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率, 所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下 /sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用 的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。

在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。

前面已经说明过了,库搜索路径的设置有两种方式:在环境变量 LD_LIBRARY_PATH 中设置以及在 /etc/ld.so.conf 文件中设置。其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:

$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH

可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:

$ echo $LD_LIBRARY_PATH

至此,库的两种设置就完成了。


Readmore »»

bash 的启动方式


  • /etc/profile

  • 全局(公有)配置,不管是哪个用户,登录时都会读取该文件。
  • /ect/bashrc

  • Ubuntu没有此文件,与之对应的是/ect/bash.bashrc,它也是全局(公有)的,bash执行时,不管是何种方式,都会读取此文件。
  • ~/.profile

  • 若bash是以login方式执行时,读取~/.bash_profile,若它不存在,则读取~/.bash_login,若前两者不存在,读取~/.profile。




另外,图形模式登录时,此文件将被读取,即使存在~/.bash_profile和~/.bash_login。
若bash是以login方式执行时,读取~/.bash_profile,若它不存在,则读取~/.bash_login,若前两者不存在,读取~/.profile。

  • ~/.bash_profile

  • Unbutu默认没有此文件,可新建。
    只有bash是以login形式执行时,才会读取此文件。通常该配置文件还会配置成去读取~/.bashrc。
  • ~/.bashrc

  • 当bash是以non-login形式执行时,读取此文件。若是以login形式执行,则不会读取此文件。
  • ~/.bash_logout

  • 注销时,且是longin形式,此文件才会读取。也就是说,在文本模式注销时,此文件会被读取,图形模式注销时,此文件不会被读取。


下面是在本机的几个例子:

  1. 图形模式登录时,顺序读取:/etc/profile和~/.profile

  2. 图形模式登录后,打开终端时,顺序读取:/etc/bash.bashrc和~/.bashrc

  3. 文本模式登录时,顺序读取:/etc/bash.bashrc,/etc/profile和~/.bash_profile


  4. 从其它用户su到该用户,则分两种情况:


    1. 如果带-l参数(或-参数,--login参数),如:su -l username,则bash是lonin的,它将顺序读取以下配置文件:/etc/bash.bashrc,/etc/profile和~/.bash_profile。

    2. 如果没有带-l参数,则bash是non-login的,它将顺序读取:/etc/bash.bashrc和~/.bashrc




  5. 注销时,或退出su登录的用户,如果是longin方式,那么bash会读取:~/.bash_logout

  6. 执行自定义的shell文件时,若使用“bash -l a.sh”的方式,则bash会读取行:/etc/profile和~/.bash_profile,若使用其它方式,如:bash a.sh, ./a.sh,sh a.sh(这个不属于bash shell),则不会读取上面的任何文件。

  7. 上面的例子凡是读取到~/.bash_profile的,若该文件不存在,则读取~/.bash_login,若前两者不存在,读取~/.profile。



Readmore »»

使用here文档

一个简单的例子使用here文档:
#!/bin/sh
cat <<!FUNKY!
hello
this is a here
document
!FUNKY!
这个脚本的输出如下:
hello
this is a here
document
here脚本最常用的就是从脚本程序中输出大量的文本。可以避免使用echo来一行行的输出文本。

Readmore »»

linux 后台调用matlab的 .m程序

测试环境:slackware12.1, matlab7.0
命令:我所使用的是一个叫做Decomp.m的matlab程序,具体的命令如下:
matlab -nodisplay -r "Decomp('image.bmp', 'image-result1.bmp', 'image-result2.bmp');exit"
-nodisplay:启用matlab但不使用gui界面
-r command: 在这里一定要注意的是command的内容一定要用双引号括起来。
";exit":的作用是执行完后退出matlab。

Readmore »»

Start Matlab from console under Unix/Linx

quote from:http://blog.4message.net/2008/10/03/start-matlab-from-console-under-unixlinx.html

Under Unix/Linux, you can run matlab without GUI,which always is so usefully for me.

For me, I run Matlab programs for long time in a remote server. If a Matlab GUI is opened ,I can’t disconnect the remote server. But when I run Matlab without GUI, I can do it with screen command.

Here is a example:

cunzhang@node31:~$ screen -S a

Then enter a visual terminal

cunzhang@node31:~$matlab -nodisplay -r myprogram

Now you can disconnect your remote server.If you want to see whether your program is done, just run command

cunzhang@node31:~$ screen -r a

For more information, please see:

1. GNU screen’s homepage

2. http://gentoo-wiki.com/TIP_Using_screen

3. http://sunsite.ualberta.ca/Documentation/Gnu/screen-3.9.4/html_chapter/screen_toc.html

4. matlab function reference

more details about matlab : matlab -h


Readmore »»

bit 与 byte

Bit 意为“位”或“比特”,是电脑运算的基础;Byte 意为“字节”,是电脑文件大小的基本计算单位。
Bit 和 Byte 同译为"比特",都是数据量度单位,bit=“比特”或“位”。
Byte=“字节”即 1 byte=8 bits,两者换算是 1:8 的关系。
我们所说的硬盘容量如:40GB、80GB、100GB,这里的 B 指是的 Byte 也就是“字节”。
  • 1 KB = 1024 bytes
  • 1 MB = 1024 KB
  • 1 GB = 1024 MB

Readmore »»

find 的常用选项及动作

find [path] [options] [tests] [actions]

options means
-depth 在查看目录本身之前先搜索目录的内容
-follow 跟随符号链接
-maxdepths N 最多搜索N层目录
-mount(or -xdev) 不搜索其他文件系统中的目录

tests means
-atime N N天前访问的文件
-mtime N N天前修改的文件
-name pattern 文件名匹配提供的模式pattern,模式必须加双引号
-newer otherfile 比otherfile要新的文件
-type c 文件类型为c的文件
-user username 文件拥有者是username的文件
组合操作符
短格式 长格式 含义
! -not 测试取反
-a -and 同时为真
-o -or 之一为真

"(" 对shell来说有特殊的意义,使用时应转义"\(", "\)"。为确保匹配模式pattern直接传给find而不是由shell来处理,应该加上""括起来。

actions means
-exec command 执行一条命令。
-ok command 执行命令之前要求用户确认
-print 打印文件名
-ls 对当前文件使用命令ls -dils

-exec与-ok 将命令行上后续的参数作为它们参数的一部分,直到被\;序列终止。魔术字符串{}是-exec或-ok命令的一个特殊类型的参数,它将被当前文件的完整路径取代。

Readmore »»

linux文件结构

节选自:http://www.linuxsir.org/main/?q=node/189

文件系统的组织结构分析,我们能分析什么呢?也就是当我们列/目录时,所看到的/usr、/etc ... ... /var 等目录是做什么用的,这些目录是不是有些特定的用途。无论哪个哪个版本的Linux系统,都有这些目录,这些目录应该是标准的。当然各个Linux发行版 本也会存在一些小小的差异,但总体来说,还是大体差不多。

Linux发行版本之间的差别其实很少,差别主要表现在系统管理的特色工具以及软件包管理方式的不同,除此之外,没有什么大的差别; 比如Fedora软件包管理工具是rpm,而Slackware是pkgtool 或installpkg等;

言归正传,我们接着说文件系统组织结构。

/ Linux文件系统的入口,也是处于最高一级的目录;

/bin 基础系统所需要的那些命令位于此目录,也是最小系统所需要的命令;比如 ls、cp、mkdir等命令;功能和/usr/bin类似,这个目录中的文件都是可执行的,普通用户都可以使用的命令。做为基础系统所需要的最基础的命令就是放在这里。

/boot Linux的内核及引导系统程序所需要的文件,比如 vmlinuz initrd.img 文件都位于这个目录中。在一般情况下,GRUB或LILO系统引导管理器也位于这个目录;

/dev 设备文件存储目录,比如声卡、磁盘... ...

/etc 系统配置文件的所在地,一些服务器的配置文件也在这里;比如用户帐号及密码配置文件;

/home 普通用户家目录默认存放目录;

/lib 库文件存放目录

/lost+found 在ext2或ext3文件系统中,当系统意外崩溃或机器意外关机,而产生一些文件碎片放在这里。当系统启动的过程中fsck工具会检查这里,并修复已经损 坏的文件系统。 有时系统发生问题,有很多的文件被移到这个目录中,可能会用手工的方式来修复,或移到文件到原来的位置上。

/media 即插即用型存储设备的挂载点自动在这个目录下创建,比如USB盘系统自动挂载后,会在这个目录下产生一个目录 ;CDROM/DVD自动挂载后,也会在这个目录中创建一个目录,类似cdrom 的目录。这个只有在最新的发行套件上才有,比如Fedora Core 4.0 5.0 等。可以参看/etc/fstab的定义;

/misc

/mnt 这个目录一般是用于存放挂载储存设备的挂载目录的,比如有cdrom 等目录。可以参看/etc/fstab的定义。有时我们可以把让系统开机自动挂载文件系统,把挂载点放在这里也是可以的。主要看/etc/fstab中怎 么定义了;比如光驱可以挂载到/mnt/cdrom 。

/opt 表示的是可选择的意思,有些软件包也会被安装在这里,也就是自定义软件包,比如在Fedora Core 5.0中,OpenOffice就是安装在这里。有些我们自己编译的软件包,就可以安装在这个目录中;通过源码包安装的软件,可以通过 ./configure --prefix=/opt/目录 。

/proc 操作系统运行时,进程(正在运行中的程序)信息及内核信息(比如cpu、硬盘分区、内存信息等)存放在这里。/proc目录伪装的文件系统proc的挂载目录,proc并不是真正的文件系统,它的定义可以参见 /etc/fstab 。

/root Linux超级权限用户root的家目录;

/sbin 大多是涉及系统管理的命令的存放,是超级权限用户root的可执行命令存放地,普通用户无权限执行这个目录下的命令,这个目录和/usr/sbin; /usr/X11R6/sbin或/usr/local/sbin目录是相似的; 我们记住就行了,凡是目录sbin中包含的都是root权限才能执行的。

/tmp 临时文件目录,有时用户运行程序的时候,会产生临时文件。/tmp就用来存放临时文件的。/var/tmp目录和这个目录相似。

/usr 这个是系统存放程序的目录,比如命令、帮助文件等。这个目录下有很多的文件和目录。当我们安装一个Linux发行版官方提供的软件包时,大多安装在这里。 如果有涉及服务器配置文件的,会把配置文件安装在/etc目录中。/usr目录下包括涉及字体目录/usr/share/fonts ,帮助目录 /usr/share/man或/usr/share/doc,普通用户可执行文件目录/usr/bin 或/usr/local/bin 或/usr/X11R6/bin ,超级权限用户root的可执行命令存放目录,比如 /usr/sbin 或/usr/X11R6/sbin 或/usr/local/sbin 等;还有程序的头文件存放目录/usr/include。

/var 这个目录的内容是经常变动的,看名字就知道,我们可以理解为vary的缩写,/var下有/var/log 这是用来存放系统日志的目录。/var/www目录是定义Apache服务器站点存放目录;/var/lib 用来存放一些库文件,比如MySQL的,以及MySQL数据库的的存放地;

一些比较重要的目录的用途;

/etc/init.d 这个目录是用来存放系统或服务器以System V模式启动的脚本,这在以System V模式启动或初始化的系统中常见。比如Fedora/RedHat;
/etc/xinit.d 如果服务器是通过xinetd模式运行的,它的脚本要放在这个目录下。有些系统没有这个目录, 比如Slackware,有些老的版本也没有。在Rehat/Fedora中比较新的版本中存在。

/etc/rc.d 这是Slackware发行版有的一个目录,是BSD方式启动脚本的存放地;比如定义网卡,服务器开启脚本等。

/etc/X11 是X-Windows相关的配置文件存放地;
比如下面的例子:

[root@localhost ~]# /etc/init.d/sshd start 注:启动sshd服务器
[root@localhost ~]# /etc/init.d/sshd stop 注:停止sshd服务器
启动 sshd: [确定]

这就是典型的sshd 服务器 System V模式启动脚本,通过这运行这个脚本可以启动sshd服务器了。

/usr/bin 这个目录是可执行程序的目录,普通用户就有权限执行; 当我们从系统自带的软件包安装一个程序时,他的可执行文件大多会放在这个目录。比如安装gaim软件包时。相似的目录是/usr/local/bin; 有时/usr/bin中的文件是/usr/local/bin的链接文件;

/usr/sbin 这个目录也是可执行程序的目录,但大多存放涉及系统管理的命令。只有root权限才能执行;相似目录是/sbin 或/usr/local/sbin或/usr/X11R6/sbin等;

/usr/local 这个目录一般是用来存放用户自编译安装软件的存放目录;一般是通过源码包安装的软件,如果没有特别指定安装目录的话,一般是安装在这个目录中。这个目录下面有子目录。自己看看吧。

/usr/lib 和/lib 目录相似,是库文件的存储目录;

/usr/share 系统共用的东西存放地,比如 /usr/share/fonts 是字体目录,是用户都共用的吧。

/usr/share/doc和/usr/share/man帮助文件,也是共用的吧;

/usr/src 是内核源码存放的目录,比如下面有内核源码目录,比如 linux 、linux-2.xxx.xx 目录等。有的系统也会把源码软件包安装在这里。比如Fedora/Redhat,当我们安装file.src.rpm的时候,这些软件包会安装在/usr /src/redhat相应的目录中。请参考: 《file.src.rpm 使用方法的简单介绍》 。另外Fedhat 4.0 5.0,他的内核源码包的目录位于/usr/src/kernels目录下的某个目录中(只有安装后才会生成相应目录);

/var/adm 比如软件包安装信息、日志、管理信息等,在Slackware操作系统中是有这个目录的。在Fedora中好象没有;自己看看吧。
/var/log 系统日志存放,分析日志要看这个目录的东西;
/var/spool 打印机、邮件、代理服务器等假脱机目录;

Readmore »»

sed命令详解

转载:http://qinghua.blog.51cto.com/202629/130674
1.sed -n '2'p filename
打印文件的第二行

2.sed -n '1,3'p filename
打印文件的1到3行

3. sed -n '/Neave/'p filename
打印匹配Neave的行(模糊匹配)

4. sed -n '4,/The/'p filename
在第4行查询模式The

5. sed -n '1,$'p filename
打印整个文件,$表示最后一行

6. sed -n '/.*ing/'p filename
匹配任意字母,并以ing结尾的单词(点号不能少)

7 sed -n / -e '/music/'= filename
打印匹配行的行号,-e 会打印文件的内容,同时在匹配行的前面标志行号。-n只打印出实际的行号

8.sed -n -e '/music/'p -e '/music/'= filename
打印匹配的行和行号,行号在内容的下面

9.sed '/company/' a\ "Then suddenly it happend" filename
选择含有company的行,将后面的内容"Then suddenly it happend"加入下一行。注意:它并不改变文件,所有操作在缓冲区,如果要保存输出,重定向到一个文件

10. sed '/company/' i\ "Then suddenly it happend" filename
同9,只是在匹配的行前插入

11.sed '/company/' c\ "Then suddenly it happend" filename
"Then suddenly it happend"替换匹配company的行的内容

12.sed '1'd ( '1,3'd '$'d '/Neave/'d) filename
删除第一行(1到3行,最后一行,匹配Neave的行)

13.[ address [,address]] s/ pattern-to-find /replacement-pattern/[g p w n]
s选项通知s e d这是一个替换操作,并查询pattern-to-find,成功后用replacement-pattern替换它
替换选项如下:
g 缺省情况下只替换第一次出现模式,使用g选项替换全局所有出现模式。
p 缺省s e d将所有被替换行写入标准输出,加p选项将使- n选项无效。- n选项不打印输出结果。
w 文件名使用此选项将输出定向到一个文件。(注意只将匹配替换的行写入文件,而不是整个内容)

14.sed s'/nurse/"hello "&/' filename
'hello '增加到'nurse' 的前面

15. sed '/company/r append.txt' filename
在匹配company的行的下一行开始加入文件append.txt的内容

16. sed '/company/'q filename
首次匹配company后就退出sed程序

只所以看sed命令,是因为我遇到了这个一个问题。
网上有很多教程,他们发表了很多程序代码,但是作者为了解释方便,都对程序作了行号编码,就像下面这样:

代码::

1:#!/bin/bash
2:#rename file extesions
3:#
4:# rfe old_extensions new_extension


假设这个文件名是tmp,那么我们可以使用下面的命令来去掉这个行号和冒号(:)

代码::


sed -e s'/^[0-9]\{1,\}://g' tmp


不过上面的命令的命令有一个缺点,那就是如果这个行号不是数字开头,而是有空格的话,那就需要修改匹配规则,规则应该修改为匹配第一个非空白字符是数字开始,后面接一个冒号的配对。命令如下:

代码::

sed -e s'/^[^0-9a-zA-Z]*[0-9]\{1,\}://g' tmp


这令我很兴奋,于是想看看sed到底有多厉害,看了以后,明白的是不是sed有多厉害,就像awk一样,他们只是把正规表达式用到了极致。

以 Redhat6.0 为测试环境
事实上在solaris下的sed命令要比linux强,但因为没有测试
环境,我这里只给在linux下经过测试的用法。
★ 命令行参数简介
★ 首先假设我们有这样一个文本文件 sedtest.txt
★ 输出指定范围的行 p
★ 在每一行前面增加一个制表符(^I)
★ 在每一行后面增加--end
★ 显示指定模式匹配行的行号 [/pattern/]=
★ 在匹配行后面增加文本 [/pattern/]a\ 或者 [address]a\
★ 删除匹配行 [/pattern/]d 或者 [address1][,address2]d
★ 替换匹配行 [/pattern/]c\ 或者 [address1][,address2]c\
★ 在匹配行前面插入文本 [/pattern/]i\ 或者 [address]i\
★ 替换匹配串(注意不再是匹配行) [addr1][,addr2]s/old/new/g
★ 限定范围后的模式匹配
★ 指定替换每一行中匹配的第几次出现
★ &代表最后匹配
★ 利用sed修改PATH环境变量
★ 测试并提高sed命令运行效率
★ 指定输出文件 [address1][,address2]w outputfile
★ 指定输入文件 [address]r inputfile
★ 替换相应字符 [address1][,address2]y/old/new/
★ !号的使用
★ \c正则表达式c 的使用
★ sed命令中正则表达式的复杂性
★ 转换man手册成普通文本格式(新)
★ sed的man手册(用的就是上面的方法)
★ 命令行参数简介

sed
-e script 指定sed编辑命令
-f scriptfile 指定的文件中是sed编辑命令
-n 寂静模式,抑制来自sed命令执行过程中的冗余输出信息,比如只
显示那些被改变的行。
不明白?不要紧,把这些肮脏丢到一边,跟我往下走,不过下面的介绍里
不包括正则表达式的解释,如果你不明白,可能有点麻烦。
★ 首先假设我们有这样一个文本文件 sedtest.txt
cat > sedtest.txt
Sed is a stream editor
----------------------
A stream editor is used to perform basic text transformations on an input stream
--------------------------------------------------------------------------------
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
sed works by making only one pass over the input(s), and is consequently more
-----------------------------------------------------------------------------
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
--------------------------------------------------------------------------------
-
★ 输出指定范围的行 p other types of editors.
sed -e "1,4p" -n sedtest.txt
sed -e "/from/p" -n sedtest.txt
sed -e "1,/from/p" -n sedtest.txt
★ 在每一行前面增加一个制表符(^I)
sed "s/^/^I/g" sedtest.txt
注意^I的输入方法是ctrl-v ctrl-i
单个^表示行首
★ 在每一行后面增加--end
sed "s/$/--end/g" sedtest.txt
单个$表示行尾
★ 显示指定模式匹配行的行号 [/pattern/]=
sed -e '/is/=' sedtest.txt
1
Sed is a stream editor
----------------------
3
A stream editor is used to perform basic text transformations on an input stream
--------------------------------------------------------------------------------
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
7
sed works by making only one pass over the input(s), and is consequently more
-----------------------------------------------------------------------------
9
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
--------------------------------------------------------------------------------
-
-
意思是分析sedtest.txt,显示那些包含is串的匹配行的行号,注意 11行中出现了is字符串
这个输出是面向stdout的,如果不做重定向处理,则不影响原来的sedtest.txt
★ 在匹配行后面增加文本 [/pattern/]a\ 或者 [address]a\
^D
sed -f sedadd.script sedtest.txt
Sed is a stream editor
A stream editor is used to perform basic text transformations on an input stream
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
sed works by making only one pass over the input(s), and is consequently more
-----------------------------------------------------------------------------
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
--------------------------------------------------------------------------------
-
-
[scz@ /home/scz/src]> sed -e "a\\
+++++++++
---------------------------------------------
找到包含from字符串的行,在该行的下一行增加+++++++++。
这个输出是面向stdout的,如果不做重定向处理,则不影响原来的sedtest.txt
很多人想在命令行上直接完成这个操作而不是多一个sedadd.script,不幸的是,这需要用?nbsp;
?nbsp;
续行符\,
[scz@ /home/scz/src]> sed -e "/from/a\\
> +++++++++" sedtest.txt
[scz@ /home/scz/src]> sed -e "a\\
> +++++++++" sedtest.txt
上面这条命令将在所有行后增加一个新行+++++++++
[scz@ /home/scz/src]> sed -e "1 a\\
> +++++++++" sedtest.txt
把下面这两行copy/paste到一个shell命令行上,效果一样
+++++++++" sedtest.txt
[address]a\ 只接受一个地址指定
对于a命令,不支持单引号,只能用双引号,而对于d命令等其他命令,同时
★ 删除匹配行 [/pattern/]d 或者 [address1][,address2]d
sed -e '/---------------------------------------------/d' sedtest.txt
Sed is a stream editor
A stream editor is used to perform basic text transformations on an input stream
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
sed works by making only one pass over the input(s), and is consequently more
efficient. But it is sed's ability to filter text in a pipeline which particular
l
y
sed -e '6,10d' sedtest.txt
删除6-10行的内容,包括6和10
sed -e "2d" sedtest.txt
删除第2行的内容
sed "1,/^$/d" sedtest.txt
删除从第一行到第一个空行之间的所有内容
注意这个命令很容易带来意外的结果,当sedtest.txt中从第一行开始并没有空行,则sed删
?nbsp;
?nbsp;
sed "1,/from/d" sedtest.txt
删除从第一行到第一个包含from字符串的行之间的所有内容,包括第一个包含
from字符串的行。
★ 替换匹配行 [/pattern/]c\ 或者 [address1][,address2]c\
sed -e "/is/c\\
**********" sedtest.txt
寻找所有包含is字符串的匹配行,替换成**********
**********
----------------------
**********
--------------------------------------------------------------------------------
While in some ways similar to an editor which permits scripted edits (such as ed
)
,
--------------------------------------------------------------------------------
-
-
**********
-----------------------------------------------------------------------------
**********
--------------------------------------------------------------------------------
-
sed -e "1,11c\\
**********" sedtest.txt----------------------
在1-12行内搜索所有from字符串,分别替换成****字符串
★ 限定范围后的模式匹配
sed "/But/s/is/are/g" sedtest.txt
对那些包含But字符串的行,把is替换成are
sed "/is/s/t/T/" sedtest.txt
对那些包含is字符串的行,把每行第一个出现的t替换成T
sed "/While/,/from/p" sedtest.txt -n
输出在这两个模式匹配行之间的所有内容
★ 指定替换每一行中匹配的第几次出现
sed "s/is/are/5" sedtest.txt
把每行的is字符串的第5次出现替换成are
★ &代表最后匹配
sed "s/^$/(&)/" sedtest.txt
给所有空行增加一对()
sed "s/is/(&)/g" sedtest.txt
给所有is字符串外增加()
sed "s/.*/(&)/" sedtest.txt
给所有行增加一对()
sed "/is/s/.*/(&)/" sedtest.txt
给所有包含is字符串的行增加一对()
★ 利用sed修改PATH环境变量
先查看PATH环境变量
[scz@ /home/scz/src]> echo $PATH
/usr/bin:/usr/bin:/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/X11R6/bin:.
去掉尾部的{ :/usr/X11R6/bin:. }
[scz@ /home/scz/src]> echo $PATH | sed "s/^\(.*\):\/usr[/]X11R6\/bin:[.]$/\1/"
/usr/bin:/usr/bin:/bin:/usr/local/bin:/sbin:/usr/sbin
去掉中间的{ :/bin: }
[scz@ /home/scz/src]> echo $PATH | sed "s/^\(.*\):\/bin:\(.*\)$/\1\2/"
/usr/bin:/usr/bin/usr/local/bin:/sbin:/usr/sbin:/usr/X11R6/bin:.
[/]表示/失去特殊意义
\/同样表示/失去意义
\1表示子匹配的第一次出现
\2表示子匹配的第二次出现
\(.*\)表示子匹配
去掉尾部的:,然后增加新的路径
PATH=`echo $PATH | sed 's/\(.*\):$/\1/'`:$HOME/src
注意反引号`和单引号'的区别。

★ 测试并提高sed命令运行效率
time sed -n "1,12p" webkeeper.db > /dev/null
time sed 12q webkeeper.db > /dev/null
可以看出后者比前者效率高。
[address]q 当碰上指定行时退出sed执行
★ 指定输出文件 [address1][,address2]w outputfile
sed "1,10w sed.out" sedtest.txt -n
将sedtest.txt中1-10行的内容写到sed.out文件中。
★ 指定输入文件 [address]r inputfile
sed "1r sedappend.txt" sedtest.txt
将sedappend.txt中的内容附加到sedtest.txt文件的第一行之后
★ 替换相应字符 [address1][,address2]y/old/new/
sed "y/abcdef/ABCDEF/" sedtest.txt
将sedtest.txt中所有的abcdef小写字母替换成ABCDEF大写字母。
★ !号的使用
sed -e '3,7!d' sedtest.txt
删除3-7行之外的所有行
sed -e '1,/from/!d' sedtest.txt
找到包含from字符串的行,删除其后的所有行
★ \c正则表达式c 的使用
sed -e "\:from:d" sedtest.txt
等价于 sed -e "/from/d" sedtest.txt
★ sed命令中正则表达式的复杂性
cat > sedtest.txt
^\/[}]{.*}[\(]$\)
^D
如何才能把该行替换成
\(]$\)\/[}]{.*}^[
★ 转换man手册成普通文本格式(新)
man sed | col -b > sed.txt
sed -e "s/^H//g" -e "/^$/d" -e "s/^^I/ /g" -e "s/^I/ /g" sed.txt > sedman
txt
删除所有退格键、空行,把行首的制表符替换成8个空格,其余制表符替换成一个空格。
★ sed的man手册(用的就是上面的方法)
NAME
sed - a Stream EDitor
SYNOPSIS
sed [-n] [-V] [--quiet] [--silent] [--version] [--help]
[-e script] [--expression=script]
[-f script-file] [--file=script-file]
[script-if-no-other-script]
[file...]
DEscriptION
Sed is a stream editor. A stream editor is used to per-
form basic text transformations on an input stream (a file
or input from a pipeline). While in some ways similar to
an editor which permits scripted edits (such as ed), sed
works by making only one pass over the input(s), and is
consequently more efficient. But it is sed's ability to
filter text in a pipeline which particularly distinguishes
it from other types of editors.
OPTIONS
Sed may be invoked with the following command-line
options:
-V
--version
Print out the version of sed that is being run and
a copyright notice, then exit.
-h
--help Print a usage message briefly summarizing these
command-line options and the bug-reporting address,
then exit.
-n
--quiet
--silent
By default, sed will print out the pattern space at
the end of each cycle through the script. These
options disable this automatic printing, and sed
will only produce output when explicitly told to
via the p command.
-e script
--expression=script
Add the commands in script to the set of commands
to be run while processing the input.
-f script-file
--file=script-file
Add the commands contained in the file script-file
to the set of commands to be run while processing
the input.
If no -e,-f,--expression, or --file options are given on
the command-line, then the first non-option argument on
the command line is taken to be the script to be executed.
If any command-line parameters remain after processing the
above, these parameters are interpreted as the names of
input files to be processed. A file name of - refers to
the standard input stream. The standard input will pro-
cessed if no file names are specified.
Command Synopsis
This is just a brief synopsis of sed commands to serve as
a reminder to those who already know sed; other documenta-
tion (such as the texinfo document) must be consulted for
fuller descriptions.
Zero-address ``commands''
: label
Label for b and t commands.
#comment
The comment extends until the next newline (or the
end of a -e script fragment).
} The closing bracket of a { } block.
Zero- or One- address commands
= Print the current line number.
a \
text Append text, which has each embedded newline pre-
ceeded by a backslash.
i \
text Insert text, which has each embedded newline pre-
ceeded by a backslash.
q Immediately quit the sed script without processing
any more input, except that if auto-print is not
diabled the current pattern space will be printed.
r filename
Append text read from filename.
Commands which accept address ranges
{ Begin a block of commands (end with a }).
b label
Branch to label; if label is omitted, branch to end
of script.
t label
If a s/// has done a successful substitution since
the last input line was read and since the last t
command, then branch to label; if label is omitted,
branch to end of script.
c \
text Replace the selected lines with text, which has
each embedded newline preceeded by a backslash.
d Delete pattern space. Start next cycle.
D Delete up to the first embedded newline in the pat-
tern space. Start next cycle, but skip reading
from the input if there is still data in the pat-
tern space.
h H Copy/append pattern space to hold space.
g G Copy/append hold space to pattern space.
x Exchange the contents of the hold and pattern
spaces.
l List out the current line in a ``visually unambigu-
ous'' form.
n N Read/append the next line of input into the pattern
space.
p Print the current pattern space.
P Print up to the first embedded newline of the cur-
rent pattern space.
s/regexp/replacement/
Attempt to match regexp against the pattern space.
If successful, replace that portion matched with
replacement. The replacement may contain the spe-
cial character & to refer to that portion of the
pattern space which matched, and the special
escapes \1 through \9 to refer to the corresponding
matching sub-expressions in the regexp.
w filename Write the current pattern space to file-
name.
y/source/dest/
Transliterate the characters in the pattern space
which appear in source to the corresponding charac-
ter in dest.
Addresses
Sed commands can be given with no addresses, in which case
the command will be executed for all input lines; with one
address, in which case the command will only be executed
for input lines which match that address; or with two
addresses, in which case the command will be executed for
all input lines which match the inclusive range of lines
starting from the first address and continuing to the sec-
ond address. Three things to note about address ranges:
the syntax is addr1,addr2 (i.e., the addresses are sepa-
rated by a comma); the line which addr1 matched will
always be accepted, even if addr2 selects an earlier line;
and if addr2 is a regexp, it will not be tested against
the line that addr1 matched.
After the address (or address-range), and before the com-
mand, a ! may be inserted, which specifies that the com-
mand shall only be executed if the address (or address-
range) does not match.
The following address types are supported:
number Match only the specified line number.
first~step
Match every step'th line starting with line first.
For example, ``sed -n 1~2p'' will print all the
odd-numbered lines in the input stream, and the
address 2~5 will match every fifth line, starting
with the second. (This is a GNU extension.)
$ Match the last line.
/regexp/
Match lines matching the regular expression regexp.
\cregexpc
Match lines matching the regular expression regexp.
The c may be any character.
Regular expressions
POSIX.2 BREs should be supported, but they aren't com-
pletely yet. The \n sequence in a regular expression
matches the newline character. There are also some GNU
extensions. [XXX FIXME: more needs to be said. At the
very least, a reference to another document which
describes what is supported should be given.]
Miscellaneous notes
This version of sed supports a \ sequence in all
regular expressions, the replacement part of a substitute
(s) command, and in the source and dest parts of a
transliterate (y) command. The \ is stripped, and the
newline is kept.
SEE ALSO
awk(1), ed(1), expr(1), emacs(1), perl(1), tr(1), vi(1),
regex(5) [well, one ought to be written... XXX], sed.info,
any of various books on sed, the sed FAQ
(http://www.wollery.demon.co.uk/sedtut10.txt,
http://www.ptug.org/sed/sedfaq.htm).
BUGS
E-mail bug reports to bug-gnu-utils@gnu.org. Be sure to
include the word ``sed'' somewhere in the ``Subject:''
field.

Sed学习笔记


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

Table of Contents

1. Sed简介

2. 定址

3. Sed命令

4. 选项

5. 元字符集

6. 实例

7. 脚本

1. Sed简介

sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令 处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输 出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。以下介绍的是Gnu版本的Sed 3.02。

2. 定址

可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。

3. Sed命令

调用sed命令有两种形式:

sed [options] 'command' file(s)

sed [options] -f scriptfile file(s)

a\

在当前行后面加入一行文本。

b lable

分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。

c\

用新的文本改变本行的文本。

d

从模板块(Pattern space)位置删除行。

D

删除模板块的第一行。

i\

在当前行上面插入文本。

h

拷贝模板块的内容到内存中的缓冲区。

H

追加模板块的内容到内存中的缓冲区

g

获得内存缓冲区的内容,并替代当前模板块中的文本。

G

获得内存缓冲区的内容,并追加到当前模板块文本的后面。

l

列表不能打印字符的清单。

n

读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。

N

追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。

p

打印模板块的行。

P(大写)

打印模板块的第一行。

q

退出Sed。

r file

从file中读行。

t label

if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。

T label

错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。

w file

写并追加模板块到file末尾。

W file

写并追加模板块的第一行到file末尾。

!

表示后面的命令对所有没有被选定的行发生作用。

s/re/string

用string替换正则表达式re。

=

打印当前行号码。

#

把注释扩展到下一个换行符以前。

以下的是替换标记

g表示行内全面替换。

p表示打印行。

w表示把行写入一个文件。

x表示互换模板块中的文本和缓冲区中的文本。

y表示把一个字符翻译为另外的字符(但是不用于正则表达式)

4. 选项

-e command, --expression=command

允许多台编辑。

-h, --help

打印帮助,并显示bug列表的地址。

-n, --quiet, --silent

取消默认输出。

-f, --filer=script-file

引导sed脚本文件名。

-V, --version

打印版本和版权信息。

5. 元字符集

^ 锚定行的开始 如:/^sed/匹配所有以sed开头的行。

$ 锚定行的结束 如:/sed$/匹配所有以sed结尾的行。

. 匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。

* 匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。

[] 匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。

[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。

\(..\) 保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。

& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。

\< 锚定单词的开始,如:/\ 锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。

x\{m\}重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。

x\{m,\} 重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。

x\{m,n\}重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。

6. 实例

删除:d命令

$ sed '2d' example-----删除example文件的第二行。

$ sed '2,$d' example-----删除example文件的第二行到末尾所有行。

$ sed '$d' example-----删除example文件的最后一行。

$ sed '/test/'d example-----删除example文件所有包含test的行。

替换:s命令

$ sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。

$ sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。

$ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加localhost,变成192.168.0.1localhost。

$ sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。

$ sed 's#10#100#g' example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。

选定行的范围:逗号

$ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。

$ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。

$ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。

多点编辑:e命令

$ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。

$ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。

从文件读入:r命令

$ sed '/test/r file' example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。

写入文件:w命令

$ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。

追加命令:a命令

$ sed '/^test/a\\--->this is a example' example<-----'this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。

插入:i命令

$ sed '/test/i\\

new line

-------------------------' example

如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。

下一个:n命令

$ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。

变形:y命令

$ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。

退出:q命令

$ sed '10q' example-----打印完第10行后,退出sed。

保持和获取:h命令和G命令

$ sed -e '/test/h' -e '$G example----- 在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空 间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。 第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中 就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。

保持和互换:h命令和x命令

$ sed -e '/test/h' -e '/check/x' example -----互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。

7. 脚本

Sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。

Readmore »»

sed 命令的详细用法

首先来点文的:sed 对文件 进行操作,可以查找, sed 在一行中 使用多个命令时,一定要加-e 命令。
- 描点(anchor)
用以标 识 于句子中的位置所在. 常见有:
^: 表示句首. 如 ^abc 表示以 abc 为首的句子.
$: 表示句尾. 如 abc$ 表示以 abc 结尾的句子.
\<: 表示词首. 如 \<abc 表示以 abc 为首的詞. \>: 表示词尾. 如 abc\> 表示以 abc 結尾的詞.

- 修饰字符(modifier)

独立表示时本身不具意义, 专门用以修改前一个 char. set 的出现次数. 常见有:
*: 表示前一个char. set 的出现次数为 0 或多次. 如 ab*c 表示 a 與 c 之间可有 0 或多个b 存在.
?: 表示前一个 char. set 的出現次数为 0 或 1 次. 如 ab?c 表示 a 与c 之间可有 0 或 1 个b 存在.
+: 表示前一个 char. set 的出现次數为 1 或多次. 如 ab+c 表示 a 與 c 之间可有 1 或多个 b 存在.
{n}: 表示前一個 char. set 的出現次數必須為 n 次. 如 ab{3}c 表示 a 與 c 之間必須有 3 個 b 存在.
{n,}: 表示前一個 char. set 的出現次數至少為 n 次. 如 ab{3,}c 表示 a 與 c 之間至少有 3 個 b 存在.
{n,m}: 表示前一個 char. set 的出現次數為 n 到 m 次. 如 ab{3,5}c 表示 a 與 c 之間有 3 到 5 個 b 存在.
. : 匹配任意一个字符(1个)
.*: 匹配任意多个字符(1或多个)
1.sed 用法介绍: sed 是一个非交互性的文本编辑器,它可以
.抽取域
.匹配正则表达式
.比较域
.增加, 附加 替换
.基本的sed 命令 和一行脚本

[root@localhost ~]# cat vs.bak
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.

[root@localhost ~]# sed -e '1,2w vs.1.bak' vs.bak # The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.

[root@localhost ~]# cat vs.1.bak
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
sed基础用法
使用sed在文件中查询文本的方式:
sed浏览输入文件时,缺省从第一行开始,有两种方式定位文本:
a. 使用行号,可以是一个简单数字,或是一个行号范围。
b. 使用正则表达式。

x #为一行号,如1
x,y #表示行号范围从x到y,如2,5表示从第2行到第5行
/pattern/ #查询包含模式的行。例如/disk/或/[a-z]/
/pattern/pattern/ #查询包含两个模式的行。例如/disk/disks/
/pattern/,x #在给定行号上查询包含模式的行。如/ribbon/,3
x,/pattern/ #通过行号和模式查询匹配行。3,/vdu/
x,y! #查询不包含指定行号x和y的行。1,2!

[root@localhost ~]# sed -e '1p' vs.bak
# The default compiled in settings are fairly paranoid. This sample file
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.

[root@localhost ~]# sed -n -e '2,3p' vs.bak
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.

[root@localhost ~]# sed -n -e '/to/p' vs.bak
# loosens things up a bit, to make the ftp daemon more usable.

[root@localhost ~]# sed -n '/to/,2p' vs.bak
# loosens things up a bit, to make the ftp daemon more usable.

-n:表示不把文档的内容 打到标准输出!!
sed -n -e '/to/=' test.txt //加行号
sed -n -e '/to/p' -e '/to/=' test.txt //打出内容 加行号
sed -e '=;p' test.txt //加行号,打印
sed -n -e '=;p' test.txt
sed -n -e '=' -e 'p' test.txt
a\附加内容 #缺省放在每一行后面

sed -e 'a\this line will be added to the end of each line!oooooooooo' test.txt

i\插入内容 #缺省放在每一行前面

sed -e 'i\this line will be inserted to the begin of each line!oooooooooo' test.txt
sed -e '/music/i\this line will be inserted to the begin of the matching line!oooooooooo' test.txt

sed -n l (小写的L) tab-space.txt

[root@localhost zsun]# sed -n l tab_space
asdasd asd\tddd$
:可以查看文本中 如果为tab 则显示为\t,如果为空格,则就显示空格

本文出自 “Fighting” 博客,转载请与作者联系!

Readmore »»

堆和栈的区别

转载:http://blog.sina.com.cn/s/blog_5821e00e010006qy.html
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区 —常量字符串就是放在这里的。程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。


二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}

二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。
2.2
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块 连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因 此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活
2.5堆和栈中的存储内容
栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
2.6存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
?

2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

堆和栈的区别主要分:
操作系统方面的堆和栈,如上面说的那些,不多说了。
还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。

Readmore »»

OpenCV图像缩放

为了让所有输入图像同样大小,需要对图像进行缩放,用OpenCV的一个缩放函数cvResize就能搞定了。

缩放程序:





#include <cv.h>

#include <highgui.h>

#include <iostream>

int main(int argc, char* argv[])

{

IplImage *src = 0; //源图像指针

IplImage *dst = 0; //目标图像指针

float scale = 0.618; //缩放倍数为0.618

CvSize dst_cvsize; //目标图像尺寸

/* the first command line parameter must be image file name */

if ( argc == 2 && (src = cvLoadImage(argv[1], 0))!=0 )

{

//如果命令行传递了需要打开的图片就无须退出,所以注释掉下面一行!

//return -1;

}

else

{

src = cvLoadImage("face.jpg", 0); //载入工作目录下文件名为“tiger.jpg”的图片。

}

dst_cvsize.width = 100; //目标图像的宽为固定 100 像素

dst_cvsize.height = src->height * ((float)dst_cvsize.width/src->width); // 高同比例放大



dst = cvCreateImage( dst_cvsize, src->depth, src->nChannels); //构造目标图象

cvResize(src, dst, CV_INTER_LINEAR); //缩放源图像到目标图像



cvNamedWindow( "src", CV_WINDOW_AUTOSIZE ); //创建用于显示源图像的窗口

cvNamedWindow( "dst", CV_WINDOW_AUTOSIZE ); //创建用于显示目标图像的窗口



cvShowImage( "src", src ); //显示源图像

cvShowImage( "dst", dst ); //显示目标图像

cvWaitKey(-1); //等待用户响应

cvReleaseImage(&src); //释放源图像占用的内存

cvReleaseImage(&dst); //释放目标图像占用的内存

cvDestroyWindow( "src" ); //销毁窗口“src

cvShowImage( "src", src ); //显示源图像

cvShowImage( "dst", dst ); //显示目标图像

cvWaitKey(-1); //等待用户响应

cvReleaseImage(&src); //释放源图像占用的内存

cvReleaseImage(&dst); //释放目标图像占用的内存

cvDestroyWindow( "src" ); //销毁窗口“src

cvDestroyWindow( "dst" ); //销毁窗口“dst

//void cvDestroyAllWindows(void);

return 0;

}


Readmore »»

文件操作小脚本1

打印出文件的全路径:
tree -a -f -i | sed -n -e '/bmp/p' -e '/jpg/p' -e '/tif/p'
只要名字中包含bmp,jpg,tif的文件。

复制深层目录脚本:
在要建立与dir1的深层目录相同的根目录(dir2)下写脚本dir:
#!/bin/sh
mkdir -p `tree -a -f -i ../dir1 | sed -n 's/..\/dir1/./ p'`
exit 0

Readmore »»

GNU选项命令getopt()与长选项命令行解析getopt_long()

原著


20 世纪 90 年代,UNIX 应用程序开始支持长选项,即一对短横线、一个描述性选项名称,还可以包含一个使用等号连接到选项的参数。

[命令行参数解析函数:getopt()]
getopt()函数声明如下:
#include <getopt.h>
extern char *optarg; extern int optind, opterr, optopt;
int getopt(int argc, char * const argv[], const char *optstring);
返回值:
成功时返回选项字符;
如果所有的选项都被处理完毕,则返回-1;
如果遇到未定义的选项字符,返回'?';
如果某个需要参数的选项字符没有带参数,则返回(*optstring == ':')?':':'?'



optstring为选项字母组成的字串,譬如":x:y:mn"。如果该字串里的某一字符后面有冒号,那么就表示这个选项要求有选项参数。

第一次调用getopt(...)时,其将返回第一个选项,同时设置getopt相关的全局变量。使用相同的参数再次调用该函数时,它将返回下一个选项,并设置相关全局变量。当遇到不可识别的选项,将返回 -1表示出错。

getopt() 所设置的全局变量包括:

char *optarg——指向当前选项参数字串(如果有)。

int optind——argv的当前索引值。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在argv[optind]至argv[argc-1]中可以找到。

int opterr——被置为非零时,若getopt()函数出错则输出出错信息。

int optopt——当发现无效选项字符时,getopt()函数返回'?'字符或':'字符,optopt中为所发现的无效选项字符。

[getopt()的自定义错误提示]
可以采用以下两种方法来改变getopt()函数的出错输出方式:

1. 在调用getopt()之前,将opterr设置为0,强制getopt()函数在发现错误时不输出任何消息。

2. 如果optstring参数的第一个字符是冒号,那么getopt()函数就会保持沉默,并根据错误情况返回不同字符,如下:

“无效选项” —— getopt()返回'?',并且optopt包含了无效选项字符(这是正常的行为);

“缺少选项参数” —— getopt()返回':'。(如果optstring的第一个字符不是冒号,那么getopt()返回'?',这将混淆其与无效选项的错误信息)

[GNU提供的getopt()函数的特点]
上面所设计的getopt()函数是UNIX支持小组提供的,其执行时一碰到不以'-'开始的 命令行参数就停止寻找选项。而GNU提供的getopt()函数与之不同,它会扫描整个命令行来寻找选项。
当调用GNU getopt()函数并处理命令行参数的时候,它重新排列argv中的元素,这样当重排结束时,所有选项都被移动到前面(在任何情况下,碰到特殊参数'--'仍将结束对选项的扫描)。

GNU getopt()第二个特点是可以在optstring中使用特殊的首字符改变getopt()的默认行为:
optstring[0] = '+',这样就与UNIX支持小组提供的getopt()很相近了。
optstring[0] = '-',会在optarg中得到命令行中的每个参数。
以上两种情况下,':'可以作为第二个字符使用。

GNU getopt()第三个特点是optstring中的选项字符后面接两个冒号,就允许该选项有可选的选项参数。在选项参数不存在的情况下,GNU getopt()返回选项字符并将optarg设置为NULL。

(字符串optstring可以下列元素,
1.单个字符,表示选项,
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
3 单个字符后跟两个冒号,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。)

Example code:
#include <stdio.h>
#include <unistd.h>

int main(int argc, char * argv[])
{
if(argc == 1)
{
printf("Usage : %s"
" -s string\n", argv[0]);
return 0;
}

char opt_char;
opterr = 0;// ignore errors
while((opt_char = getopt(argc, argv, "s:")) != -1)
{
switch(opt_char)
{
case 's':
printf("You arg is %s\n", optarg);
break;
case '?':
case ':'://hehe... = =!~
printf("Argument wrong, you should check it\n");
return 0;
}
}

if(optind == (argc - 1))
{
printf("You should input an opt char.\n");
return 0;
}
return 0;
}
/********************************************************************************************************/

GNU提供了getopt-long()和getopt-long-only()函数支持长选项的命令行解析,其中,后者的长选项字串是以一个短横线开始的,而非一对短横线。

getopt_long() 是同时支持长选项和短选项的 getopt() 版本。下面是它们的声明:

#include <getopt.h>

int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

int getopt_long_only(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex);

getopt_long ()的前三个参数与上面的getopt()相同,第4个参数是指向option结构的数组,option结构被称为“长选项表”。longindex参数 如果没有设置为NULL,那么它就指向一个变量,这个变量会被赋值为寻找到的长选项在longopts中的索引值,这可以用于错误诊断。

option结构在getopt.h中的声明如下:

struct option{
const char *name;
int has_arg;
int *flag;
int val;
};

对结构中的各元素解释如下:

const char *name

这是选项名,前面没有短横线。譬如"help"、"verbose"之类。

int has_arg

描述了选项是否有选项参数。如果有,是哪种类型的参数,此时,它的值一定是下表中的一个。
符号常量 数值 含义
no_argument 0 选项没有参数
required_argument 1 选项需要参数
optional_argument 2 选项参数可选

int *flag

如果这个指针为NULL,那么getopt_long()返回该结构val字段中的数 值。如果该指针不为NULL,getopt_long()会使得它所指向的变量中填入val字段中的数值,并且getopt_long()返回0。如果 flag不是NULL,但未发现长选项,那么它所指向的变量的数值不变。

int val

这个值是发现了长选项时的返回值,或者flag不是NULL时载入*flag中的值。典型情况下,若flag不是NULL,那么val是个真/假值,譬如1 或0;另一方面,如果flag是NULL,那么val通常是字符常量,若长选项与短选项一致,那么该字符常量应该与optstring中出现的这个选项的参数相同。

每个长选项在长选项表中都有一个单独条目,该条目里需要填入正确的数值。数组中最后的元素的值应该全是0。数组不需要排序,getopt_long()会进行线性搜索。但是,根据长名字来排序会使程序员读起来更容易。

以上所说的flag和val的用法看上去有点混乱,但它们很有实用价值,因此有必要搞透彻了。

大部分时候,程序员会根据getopt_long()发现的选项,在选项处理过程中要设置一些标记变量,譬如在使用getopt()时,经常做出如下的程序格式:

int do_name, do_gf_name, do_love; /*标记变量*/
char *b_opt_arg;

while((c = getopt(argc, argv, ":ngl:")) != -1)
{
switch (c){
case 'n':
do_name = 1;
case 'g':
do_gf_name = 1;
break;
break;
case 'l':
b_opt_arg = optarg;//
optarg——指向当前选项参数(如果有)的指针。

……
}
}

当flag 不为NULL时,getopt_long*()会为你设置标记变量。也就是说上面的代码中,关于选项'n'、'l'的处理,只是设置一些标记,如果 flag不为NULL,时,getopt_long()可以自动为各选项所对应的标记变量设置标记,这样就能够将上面的switch语句中的两种种情况减 少到了一种。下面给出一个长选项表以及相应处理代码的例子。

清单5:

#include <stdio.h>
#include <getopt.h>

int do_name, do_gf_name;
char *l_opt_arg;

struct option longopts[] = {
{ "name", no_argument, &do_name, 1 },
{ "gf_name", no_argument, &do_gf_name, 1 },
{ "love", required_argument, NULL, 'l' },
{ 0, 0, 0, 0},
};

int main(int argc, char *argv[])
{
int c;

while((c = getopt_long(argc, argv, ":l:", longopts, NULL)) != -1){
switch (c){
case 'l':
l_opt_arg = optarg;
printf("Our love is %s!\n", l_opt_arg);
break;
case 0:
printf("getopt_long()设置变量 : do_name = %d\n", do_name);
printf("getopt_long()设置变量 : do_gf_name = %d\n", do_gf_name);
break;
}
}
return 0;
}

在进行测试之前,再来回顾一下有关option结构中的指针flag的说明吧。

如果这个指针为NULL,那么getopt_long()返回该结构val字段中的数值。如果该指针 不为NULL,getopt_long()会使得它所指向的变量中填入val字段中的数值,并且getopt_long()返回0。如果flag不是 NULL,但未发现长选项,那么它所指向的变量的数值不变。

下面测试一下:

$ ./long_opt_demo --name
getopt_long()设置变量 : do_name = 1
getopt_long()设置变量 : do_gf_name = 0

$ ./long_opt_demo --gf_name
getopt_long()设置变量 : do_name = 0
getopt_long()设置变量 : do_gf_name = 1

$ ./long_opt_demo --love forever
Our love is forever!

$ ./long_opt_demo -l forever
Our love is forever

测试过后,应该有所感触了。关于flag和val的讨论到此为止。下面总结一下get_long()的各种返回值的含义:

返回值 含 义
0 getopt_long()设置一个标志,它的值与option结构中的val字段的值一样
1 每碰到一个命令行参数,optarg都会记录它
'?' 无效选项
':' 缺少选项参数
'x' 选项字符'x'
-1 选项解析结束

从实用的角度来说,我们更期望每个长选项都对应一个短选项,这种情况下,在option结构中,只要将flag设置为NULL,并将val设置为长选项所对应的短选项字符即可。譬如上面清单5中的程序,修改如下。

清单6:

#include <stdio.h>
#include <getopt.h>

int do_name, do_gf_name;
char *l_opt_arg;

struct option longopts[] = {
{ "name", no_argument, NULL, 'n' },
{ "gf_name", no_argument, NULL, 'g' },
{ "love", required_argument, NULL, 'l'},
{ 0, 0, 0, 0},
};

int main(int argc, char *argv[])
{
int c;

while((c = getopt_long(argc, argv, ":l:", longopts, NULL)) != -1){
switch (c){
case 'n':
printf("My name is LYR.\n");
break;
case 'g':
printf("Her name is BX.\n");
break;
case 'l':
l_opt_arg = optarg;
printf("Our love is %s!\n", l_opt_arg);
break;
}
}
return 0;
}

测试结果如下:

$ ./long_opt_demo --name --gf_name --love forever
My name is LYR.
Her name is BX.
Our love is forever!

$ ./long_opt_demo -ng -l forever
My name is LYR.
Her name is BX.
Our love is forever!

9、在LINUX之外的系统平台上使用GNU getopt()或getopt_long()

只要从GNU程序或GNU C Library(GLIBC)的CVS档案文件中copy源文件即可(http://sourceware.org/glibc/)。所需源文件是 getopt.h、getopt.c和getoptl.c,将这些文件包含在你的项目中。另外,你的项目中最好也将COPYING.LIB文件包含进去, 因为GNU LGPL(GNU 程序库公共许可证)的内容全部包括在命名为COPYING.LIB 的文件中。

10、结论 程序需要能够快速处理各个选项和参数,且要求不会浪费开发人员的太多时间。在这一点上,无论是GUI(图形用户交互)程序还是CUI(命令行交互)程序, 都是其首要任务,其区别仅在于实现方式的不同。GUI通过菜单、对话框之类的图形控件来完成交互,而CUI使用了纯文本的交互方式。在程序开发中,许多测 试程序用CUI来完成是首选方案。

getopt() 函数是一个标准库调用,可允许您使用直接的 while/switch 语句方便地逐个处理命令行参数和检测选项(带或不带附加的参数)。与其类似的 getopt_long() 允许在几乎不进行额外工作的情况下处理更具描述性的长选项,这非常受开发人员的欢迎。




Readmore »»

Linux下的分区

转载
Linux下的分区:
   首先,
Linux对每一个设备进行了命名:
   IDE设备:一台PC上可以有两个IDE接口(我将其称为第一IDE、第二IDE),而每个IDE接口上可以接两个IDE设备(我将其称为主盘、从盘)。其中硬盘与光驱都是IDE设备。Linux这样为其命名:
第一IDE的主盘:/dev/hda
第一IDE的从盘:/dev/hdb
第二IDE的主盘:/dev/hdc
第二IDE的从盘:/dev/hdd

   SCSI设备:这个相对大家会陌生一些,它通常需要加上一块SCSI卡来驱动。第一块SCSI设备称为:/dev/sda、第二块就是/dev/sdb……以此类推。
为什么都有一个“/dev”呢,这是因为,在UNIX/LINUX系统中,将所有的设备都当做一个文件,放在/dev目录下。
主分区(或扩展分区)被命名为hda1-hda4,如果没有,就跳过。而扩展分区中的逻辑分区则从hda5开始编号,以此类推。
注意了,这里是以第一IDE的主盘为例,如果是第二硬盘,就是hdb1、hdb2、hdb5、hdb6、hdb7。
到此,我们可以发现,Windows下不管有多少个IDE设备都是顺序地分配盘符,而在Linux下是认真区分对待每一个硬盘的。
为Linux划分分区:
   大家都知道,Windows下每一个分区都可利用于存放文件,而在Linux则除了存放文件的分区外,还需要一个“Swap(交换)分区”用来补充内存,因此通常需要两个分区:
   1. 主分区:学习使用的话,建议2G;

   2. 交换分区:只需1-2倍内存的大小,若64-128M内存,交换分区可为128M,128-256M内存,交换分区可为256M。
   由于早期的Linux启动器LILO无法识别8G以外的硬盘分区,因此建议将Linux两个分区分在8G以内。

在Linux下,传统的IDE接口的硬盘会被识别为“hda”、“hdb”这样命名格式的设备,而SCSI接口的硬盘会被识别为“sda”、“sdb”格 式。以后者为例,如果计算机中只有一块硬盘,它就是“sda”,第二块硬盘会被识别为“sdb”,依次类推。Linux为第一块硬盘的四个主分区分配的设 备名分别为“sda1”、“sda2”、“sda3”和“sda4”,而从“sda5”到“sda16”则分别为预留的逻辑分区的设备名。例如我本机的 Windows使用的C盘在Linux下被识别为“sda1”,而Windows的D盘为扩展分区的第一个逻辑分区,因此被识别为“sda5”

Readmore »»