常用的linux命令以及常用shell语句(基于ubuntu16&MACBOOK)

ubuntu16常用linux命令

1. ubuntu16解压缩文件命令

以下部分转载自博客(http://blog.csdn.net/feibendexiaoma/article/details/73739279)

1.1 ZIP

zip是比较常用的文档压缩格式,最大的有点是跨平台,缺点是支持的压缩率不是很高。
-r即循环压缩子文件夹

压缩
zip -r studio.zip directory_to_compress

解压
unzip studio.zip

1.2 TAR

好处是只消耗非常少的CPU及时间来打包,只是一个打包工具,并不负责压缩。
tar -cvf studio.tar directory_to_compress

解包 到当前目录下
tar -xvf studio.tar
到指定目录下
tar -xvf studio.tar -C /tmp/extract/

1.3.TAR.GZ

压缩时不会占用太多的CPU,就可以得到一个非常理想的压缩率。
压缩
tar -zcvf studio.tar.gz directory_to_compress
解压到当前目录
tar -zxvf studio.tar.gz
到指定目录
tar -zxvf studio.tar.gz -C /tmp/extract/

1.4.TAR.BZ2

这种压缩格式是这几种方式中压缩率最好的
tar -jcvf studio.tar.bz2 directory_to_compress
解压 到当前目录
tar -jxvf studio.tar.bz2
到指定目录
tar -jxvf studio.tar.bz2 -C /tmp/extract/

2. ubuntu16常用命令:

2.1关机命令:

1、halt 立刻关机
2、poweroff 立刻关机
3、shutdown -h now 立刻关机(root用户使用)
4、shutdown -h 10 10分钟后自动关机 如果是通过shutdown命令设置关机的话,可以用shutdown -c命令取消重启

2.2重启命令:

1、reboot
2、shutdown -r now 立刻重启(root用户使用)
3、shutdown -r 10 过10分钟自动重启(root用户使用)
4、shutdown -r 20:35 在时间为20:35时候重启(root用户使用) 如果是通过shutdown命令设置重启的话,可以用shutdown -c命令取消重启

2.3下载命令:

wget

参数

URL:下载指定的URL地址。

实例

使用wget下载单个文件
wget http://www.linuxde.net/testfile.zip

测试下载链接

当你打算进行定时下载,你应该在预定时间测试下载链接是否有效。我们可以增加--spider参数进行检查。

wget --spider URL
如果下载链接正确,将会显示:

Spider mode enabled. Check if remote file exists.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.
这保证了下载能在预定的时间进行,但当你给错了一个链接,将会显示如下错误:

wget --spider url
Spider mode enabled. Check if remote file exists.
HTTP request sent, awaiting response... 404 Not Found
Remote file does not exist -- broken link!!!

下载多个文件

wget -i filelist.txt

首先,保存一份下载链接文件:
用cat命令查看一下文件中的url
查看文件内容可以使用cat或者text命令
cat > filelist.txt
url1
url2
url3
url4
接着使用这个文件和参数-i下载。

镜像网站

wget --mirror -p --convert-links -P ./LOCAL URL
下载整个网站到本地。

--miror开户镜像下载。
-p下载所有为了html页面显示正常的文件。
--convert-links下载后,转换成本地的链接。
-P ./LOCAL保存所有文件和目录到本地指定目录。

FTP下载

wget ftp-url
wget --ftp-user=USERNAME --ftp-password=PASSWORD url
可以使用wget来完成ftp链接的下载。

使用wget匿名ftp下载:
wget ftp-url
使用wget用户名和密码认证的ftp下载:
wget --ftp-user=USERNAME --ftp-password=PASSWORD url

2.4查找命令:

which:常用于查找可直接执行的命令。只能查找可执行文件,该命令基本只在$PATH路径中搜索,查找范围最小,查找速度快。默认只返回第一个匹配的文件路径,通过选项 -a 可以返回所有匹配结果。
whereis:不只可以查找命令,其他文件类型都可以(man中说只能查命令、源文件和man文件,实际测试可以查大多数文件)。在$PATH路径基础上增加了一些系统目录的查找,查找范围比which稍大,查找速度快。可以通过 -b 选项,限定只搜索二进制文件。
locate:超快速查找任意文件。它会从linux内置的索引数据库查找文件的路径,索引速度超快。刚刚新建的文件可能需要一定时间才能加入该索引数据库,可以通过执行updatedb命令来强制更新一次索引,这样确保不会遗漏文件。该命令通常会返回大量匹配项,可以使用 -r 选项通过正则表达式来精确匹配。
find:直接搜索整个文件目录,默认直接从根目录开始搜索,建议在以上命令都无法解决问题时才用它,功能最强大但速度超慢。除非你指定一个很小的搜索范围。通过 -name 选项指定要查找的文件名,支持通配符。

find:

-path:要查找的目录路径。
~ 表示$HOME目录
. 表示当前目录
/ 表示根目录
-print:表示将结果输出到标准输出。

-exec:对匹配的文件执行该参数所给出的shell命令。
形式为command {} ;,注意{}与;之间有空格

-ok:与exec作用相同,
区别在于,在执行命令之前,都会给出提示,让用户确认是否执行

|xargs 与exec作用相同 ,起承接作用
区别在于 |xargs 主要用于承接删除操作 ,而 -exec 都可用 如复制、移动、重命名等
find /data/xxxx1/xxxx2 -maxdepth 1 -type f -mtime 50 | xargs -r rm

使用-type查找指定文件类型的文件
find / -type d -name xxx
find . -type f -name xxx.php

基于时间查询文件或目录
find / -mtime 50
find / -mtime +10

使用mindepth和maxdepth限定搜索指定目录的深度
在root目录及其1层深的子目录中查找xxxx.
find -maxdepth 2 -name xxxx
在root目录下及其最大两层深度的子目录中查找xxxx文件.
find / -maxdepth 3 -name xxxx

在第二层子目录和第四层子目录之间查找xxxx文件。
find -mindepth 3 -maxdepth 5 -name xxxx

2.5后台运行:

很多集群会动态分配资源,动态的关闭一些链接,这时候集群中的任务就需要用到nohup命令
nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。

nohup和&的区别
& : 指在后台运行
nohup : 不挂断的运行,注意并没有后台运行的功能,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,例如我们断开SSH连接都不会影响他的运行,注意了nohup没有后台运行的意思;&才是后台运行

3.Linux 文件与目录管理

绝对路径:
路径的写法,由根目录 / 写起,例如: /usr/share/doc 这个目录。
相对路径:
路径的写法,不是由 / 写起,例如由 /usr/share/doc 要到 /usr/share/man 底下时,可以写成: cd ../man 这就是相对路径的写法

3.1 列出目录

ls
-a :全部的文件,连同隐藏档( 开头为 . 的文件) 一起列出来(常用)
-d :仅列出目录本身,而不是列出目录内的文件数据(常用)
-l :长数据串列出,包含文件的属性与权限等等数据;(常用)
-ll:加上具体的文件大小
-lh:加上具体文件的大小(更直观)
将HOME目录下的所有文件列出来(含属性与隐藏档)
[root@www ~]# ls -al ~

3.2 切换目录

cd
cd [相对路径或绝对路径]

#使用 mkdir 命令创建 runoob 目录
[root@www ~]# mkdir runoob

#使用绝对路径切换到 runoob 目录
[root@www ~]# cd /root/runoob/

#使用相对路径切换到 runoob 目录
[root@www ~]# cd ./runoob/

# 表示回到自己的家目录,亦即是 /root 这个目录
[root@www runoob]# cd ~

# 表示去到目前的上一级目录,亦即是 /root 的上一级目录的意思;
[root@www ~]# cd ..

3.3 创建目录删除目录

mkdir
-m :创建目录时直接配置文件的权限
-p :递归的创建多层文件夹

mkdir test
mkdir -p test1/test2/test3/test4
mkdir -m 777 test5

rmdir (删除空的目录)
-p :连同上一级『空的』目录也一起删除
rmdir -p test1/test2/test3/test4
rmdir 仅能删除空的目录,需要使用 rm 命令来删除非空目录

3.4 访问根目录

pwd
pwd命令以绝对路径的方式显示用户当前工作目录。命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用/分隔。第一个/表示根目录,最后一个目录是当前目录。执行pwd命令可立刻得知您目前所在的工作目录的绝对路径名称。

3.5 拷贝文件

拷贝当前文件夹文件model.bin 到data/model 文件夹
cp ./model.bin ./data/model/model.bin
用 root 身份,将 root 目录下的 .bashrc 复制到 /tmp 下,并命名为 bashrc

[root@www ~]# cp ~/.bashrc /tmp/bashrc
[root@www ~]# cp -i ~/.bashrc /tmp/bashrc
cp: overwrite `/tmp/bashrc'? n  <==n不覆盖,y为覆盖

选项与参数:
-a:相当於 -pdr 的意思,至於 pdr 请参考下列说明;(常用)
-d:若来源档为连结档的属性(link file),则复制连结档属性而非文件本身;
-f:为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;
-i:若目标档(destination)已经存在时,在覆盖时会先询问动作的进行(常用)
-p:连同文件的属性一起复制过去,而非使用默认属性(备份常用);
-r:递归持续复制,用於目录的复制行为;(常用)
把fastText文件夹复制到/home/up/文件夹下

cp -r /home/wangyao/up/fastText /home/up/fastText

3.6 移除文件或目录

rm
-f :就是 force 的意思,忽略不存在的文件,不会出现警告信息;
-i :互动模式,在删除前会询问使用者是否动作
-r :递归地删除整个文件夹以及子文件,最常用在目录的删除

删除时询问是否删除此文件夹
rm -i test
删除一个路径名称
rm -rf $model_dir
删除一个多层的文件夹
rm -rf test1
删除当前文件夹下所有文件
rm -rf *

3.7 移除文件或目录,或修改名称

mv
-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
-i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!
-u :若目标文件已经存在,且 source 比较新,才会升级 (update)

在当前文件夹中创建两个文件夹
mkdir test1
mkdir test2
把test1放进test2中
mv test1 test2
给test2重命名为test3
mv test2 test3

3.8 linux文件内容查看

Linux系统中使用以下命令来查看文件的内容:

cat 由第一行开始显示文件内容,详细用法见5.cat命令
tac 从最后一行开始显示,可以看出 tac 是 cat 的倒著写!
nl 和cat类似,但是结果会输出行号
more 一页一页的显示文件内容,按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示。
less 与 more 类似,但是比 more 更好的是,他可以往前翻页
head 只看头几行 head -1
tail 只看尾巴几行
你可以使用 man [命令]来查看各个命令的使用文档,如 :man cp。

wc是wordcount的缩写,可以查看文件行数或者单词数等等。

文件行数,从0开始计数:wc -l filename
wc -l a.txt
文件单词数:wc -w filename
wc -w a.txt
文件字符数,空格也算一个字符:wc -c filename
wc -c a.txt

4.Linux磁盘管理

Linux磁盘管理好坏直接关系到整个系统的性能问题。
Linux磁盘管理常用三个命令为df、du和fdisk。

df:列出文件系统的整体磁盘使用量
du:检查磁盘空间使用量
fdisk:用于磁盘分区

4.1 df

df命令参数功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。

语法:
df [-ahikHTm] [目录或文件名]
选项与参数:
-a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
-k :以 KBytes 的容量显示各文件系统;
-m :以 MBytes 的容量显示各文件系统;
-h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
-H :以 M=1000K 取代 M=1024K 的进位方式;
-T :显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
-i :不用硬盘容量,而以 inode 的数量来显示

4.2 du

Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的,这里介绍Linux du命令。
语法:
du [-ahskm] 文件或目录名称
选项与参数:
-a :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
-h :以人们较易读的容量格式 (G/M) 显示;
-s :列出总量而已,而不列出每个各别的目录占用容量;
-S :不包括子目录下的总计,与 -s 有点差别。
-k :以 KBytes 列出容量显示;
-m :以 MBytes 列出容量显示;

通常:du -sh * 可以看一下当前文件占磁盘的空间。

4.3 fdisk

fdisk 是 Linux 的磁盘分区表操作工具。
fdisk [-l] 装置名称
选项与参数:

-l :输出后面接的装置所有的分区内容。若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜寻到的装置的分区均列出来。

5.cat命令

cat命令主要用来查看文件内容,创建文件,文件合并,追加文件内容等功能。
参数:
-n 或 –number 由 1 开始对所有输出的行数编号
-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 –show-nonprinting

5.1 A:查看文件内容主要用法:

1、cat f1.txt,查看f1.txt文件的内容。
2、cat -n f1.txt,查看f1.txt文件的内容,并且由1开始对所有输出行进行编号。
3、cat -b f1.txt,查看f1.txt文件的内容,用法与-n相似,只不过对于空白行不编号。
4、cat -s f1.txt,当遇到有连续两行或两行以上的空白行,就代换为一行的空白行。
5、cat -e f1.txt,在输出内容的每一行后面加一个$符号。
6、cat f1.txt f2.txt,同时显示f1.txt和f2.txt文件内容,注意文件名之间以空格分隔,而不是逗号。
7、cat -n f1.txt>f2.txt,对f1.txt文件中每一行加上行号后然后写入到f2.txt中,会覆盖原来的内容,文件不存在则创建它,输出重定向。
8、cat -n f1.txt>>f2.txt,对f1.txt文件中每一行加上行号后然后追加到f2.txt中去,不会覆盖原来的内容,文件不存在则创建它。
9、cat /dev/null > /etc/test.txt 此为清空/etc/test.txt档案内容,把结果重定向到/dev/null中,/dev/null是linux中只进不出的垃圾桶。

范例:
cat -n linuxfile1 > linuxfile2 把 linuxfile1 的档案内容加上行号后输入 linuxfile2 这个档案里
cat -b linuxfile1 linuxfile2 >> linuxfile3 把 linuxfile1 和 linuxfile2 的档案内容加上行号(空白行不加)之后将内容附加到linuxfile3 里。
范例:
把 linuxfile1 的档案内容加上行号后输入 linuxfile2 这个档案里
cat -n linuxfile1 > linuxfile2
把 linuxfile1 和 linuxfile2 的档案内容加上行号(空白行不加)之后将内容附加到 linuxfile3 里。
cat -b linuxfile1 linuxfile2 >> linuxfile3

5.2 B:创建文件以及写入文件内容的用法:

注意:创建文件的时候要设置文件结束标志,也就是<

cat>test< it
> is
> a
> test
> EOF
cat test
结果:
it
is
a
test

5.3 C:追加文件内容的用法:

注意:与创建文件内容不同的是符号单边号>变成了双边号>>。

cat>>test< over
> EOF
cat test
结果:
it
is
a
test
over

5.4 D:文件合并的用法

cat>test1<my name is
> EOF
cat>test2<pipixia
> EOF

把文件test1,test2的文件内容写入到new_test中,如果new_test文件以前有内容,则先会清除它们然后再写入合并后的内容。
如果不想清除文件内容,则可以把单边号>变成了双边号>>:

cat test1 test2 >new_test
cat new_test
结果:
my name is
pipixia

https://www.cnblogs.com/zhangchengxiang/p/5195583.html

6.计算器,bc 命令

bc 命令是任意精度计算器语言,通常在linux下当计算器用。
它类似基本的计算器, 使用这个计算器可以做基本的数学运算。

常用的运算:
+ 加法
- 减法
* 乘法
/ 除法
^ 指数
% 余数
语法
bc(选项)(参数)

选项值
-i:强制进入交互式模式;
-l:定义使用的标准数学库; 
-w:对POSIX bc的扩展给出警告信息;
-q:不打印正常的GNU bc环境信息;
-v:显示指令版本信息;
-h:显示指令的帮助信息。

参数
文件:指定包含计算任务的文件。

通常配合管道符号来使用:

echo "15+5" | bc
输出结果:
20

scale=2 设小数位,2 代表保留两位:
echo 'scale=2; (2.777 - 1.4744)/1' | bc
输出结果:
1.30

bc 除了 scale 来设定小数位之外,还有 ibase 和 obase 来其它进制的运算:
echo "ibase=2;111" |bc
输出结果:
7

abc=192 
echo "obase=2;$abc" | bc
执行结果为:11000000,这是用bc将十进制转换成二进制。

abc=11000000 
echo "obase=10;ibase=2;$abc" | bc
执行结果为:192,这是用bc将二进制转换为十进制。
计算平方和平方根:
echo "10^10" | bc 
输出结果:
10000000000
echo "sqrt(100)" | bc
输出结果:
10

计算完以后通常把结果赋值
num=$(echo "scale=2; 10*0.25/1" | bc)
echo num
输出结果:
2.50

7.source,export,bash命令,sh命令

7.1 source命令

source命令通常用来使一些配置立即生效,看到以下这篇博客介绍得比较详细。
摘自:http://www.51testing.com/html/38/225738-206878.html
source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令。
功能:使Shell读入指定的Shell程序文件并依次执行文件中的所有语句
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
用法:
source filename 或 . filename
source命令(从 C Shell 而来)是bash shell的内置命令;点命令(.),就是个点符号(从Bourne Shell而来)是source的另一名称。

source filename 与 sh filename 及./filename执行脚本的区别在那里呢?
1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有"."是用来表示当前目录的。
2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。
3.source filename这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。

举例说明:
1.新建一个test.sh脚本,内容为:A=1
2.然后使其可执行chmod +x test.sh
3.运行sh test.sh后,echo $A,显示为空,因为A=1并未传回给当前shell
4.运行./test.sh后,也是一样的效果
5.运行source test.sh 或者 . test.sh,然后echo $A,则会显示1,说明A=1的变量在当前shell中

7.2 export命令

export命令用于设置或显示环境变量。
在shell中执行程序时,shell会提供一组默认的环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export仅仅生效于此次登陆操作,注销或者重新开一个窗口,export命令添加的环境变量都不存在了。
用法:
export [-fnp][变量名称]=[变量设置值]
其中:

-f  代表[变量名称]中为函数名称。
-n  删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。
-p  列出所有的shell赋予程序的环境变量。
你可以只打出export来查看当前的所有环境变量。如果你要在某个环境变量(比如PATH)中加入一些新的路径(如/bin/bash),可以使用如下命令格式
export PATH=/bin/bash:$PATH

7.2 bash命令

执行脚本命令

./openspark.sh
sh openspark.sh
bash openspark.sh

7.3 sh命令

shell脚本调试
1. 几种不错的调试方法
(1)使用echo打印信息
(2)命令行中使用sh -x script.sh
(3)shell脚本中设置
set -x 开启调试、
set +x 禁止调试

2. 调试方式的选择
首选调试方式sh -x ,简单便捷。她能跟踪执行信息,将执行脚本的过程中把实际执行的每个命令显示出来,行首显示+, +后面显示经过替换之后的命令行内容,有助于分析实际执行的是什么命令.
这里也相当于打印出来了执行的命令。

8.Shell基础

8.1 字符串输出

字符串输出通常使用echo和printf
其中echo会自动换行,printf不会,printf和c语言中的printf类似。
通常使用echo就行了
echo详解
echo string

echo "shell test"
echo shell test
双引号可省略,结果一样:shell test

转义字符
echo "\"shell test\""
结果:
"shell test"
同样,双引号也可以省略

显示变量

#read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
#!/bin/sh
read name 
echo "$name shell test"

touch test.sh新建shell脚本
chmod 777 test.sh
,把以上代码保存进test.sh,name 接收标准输入的变量,结果将是:
sh test.sh或./test.sh
OK #标准输入
OK shell test #输出
显示换行和不换行
换行

#!/bin/sh
echo -e "OK! \n" # -e 开启转义
echo "It is a test"
输出结果:
OK!

It it a test

不换行

#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"
输出结果:OK! It is a test
转义
    \a 发出警告声;

    \b 删除前一个字符;

    \c 最后不加上换行符号;

    \f 换行但光标仍旧停留在原来的位置;

    \n 换行且光标移至行首;

    \r 光标移至行首,但不换行;

    \t 插入tab;

    \v 与\f相同;

    \\ 插入\字符;

    \nnn 插入nnn(八进制)所代表的ASCII字符;

原样输出字符串,不进行转义或取变量(用单引号框住需要输出的内容)
echo '$name\"'
输出结果:
$name"
显示linux命令执行结果(使用反引号"`"符号)
echo `date`
Thu Jul 24 10:08:46 CST 2014

8.2 history

查看历史命令
history
删除历史命令
history -c

8.3 shell特殊字符以及多命令执行

8.3.1.特殊字符:

$0 这个程式的执行名字
当前这个shell脚本的地址可以这样表示:path=$(cd `dirname $0`; pwd)
$n 这个程式的第n个参数值,n=1..9
注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

另外,还有几个特殊字符用来处理参数:
$* 这个程式的所有参数,此选项参数可超过9个。
以一个单字符串显示所有向脚本传递的参数。
如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$# 这个程式的参数个数
$$ 这个程式的PID(脚本运行的当前[进程ID]号)
$! 执行上一个背景指令的PID(后台运行的最后一个进程的[进程ID]号)
$? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
$- 显示shell使用的当前选项,与set命令功能相同
$@ 跟$*类似,但是可以当作数组用

8.3.2.多命令执行

多命令执行符 格 式 作 用
I 命令1 I 命令2 把第一条命令执行的结果传递给第二条命令(管道符号)
命令1 ; 命令2 多条命令顺序执行,命令之间没有任何逻辑关系
&& 命令1 && 命令2 如果命令1正确执行($?=0),则命令2才会执行,如果命令1执行不正确($?≠0),则命令2不会执行
II 命令1II 命令2 如果命令1执行不正确($?≠0),则命令2才会执行,如果命令1正确执行($?=0),则命令2不会执行
() (命令1;命令2....) 多个命令之间用;分隔 在当前文件夹整体执行括号中的命令,即使括号里有切换文件夹的命令,执行的时候也不会切换。
{} {命令1;命令2....} 在使用{}是,{}与命令之间必须有一个空格 如果使用{}来代替(),那么相应的命令将在子shell而不是当前shell中作为一个整体被执行,只有在{}中所有命令的输出作为一个整体被重定向时,其中的命令才被放到子shell中执行,否则在当前shell执行。
{}运算符例子
A=1;echo $A;{ A=2; };echo $A
输出结果:
1
2
A=1;echo $A;( A=2; );echo $A
输出结果:
1
1

8.4 if 判断语句

使用if判断语句之前:

需要知道一些关于空格的基本语法问题。

以下情况,必须有空格:

注意:也可以使用"==",但是如果if [ 判断条件 ]中 == 左右没有空格,不会报错并且按照True来执行,所以不建议使用"=="
    (1) 条件测试语句中[ ]符号左右两边:

        if [ $a = 1 ];then

            .....

        fi

    (2) 字符串比较中比较符号左右两边:

        if [ $str != string1 ];then

            ......

        fi

    (3) 算术运算比较中比较参数左右两边:

        if [ $num -eq 1 ];then

            ......

        fi

    (4) 逻辑运算中逻辑运算法左右两边:
        -a         与
        -o        或
        !         非
        if [ $str != string1 -a $num -eq 1 ];then

            ......

        fi
    
     (5) 使用{ 命令1;命令2... }运算符执行多个命令时:
{}和命令之间一定要有空格

不能有空格的情况:

变量赋值时"="的左右,因为此时的空格是用来分割命令行的赋值和后续的命令行的。

a=111
另外有的时候需要在if语句中加入exit退出程序。

通常这样写

#当参数个数不等于1,报错
if [ "$#" -ne 1 ]; then
    echo "fail"
    exit 1
else
    num=$1
    echo  "it works"
fi

当你 exit 0 的时候,在调用环境 echo $? 就返回0,也就是说调用环境就认为你的这个程序执行正确。
当你 exit 1 的时候,一般是出错定义这个1,也可以是其他数字,很多系统程序这个错误编号是有约定的含义的。但不为0 就表示程序运行出错。调用环境就可以根据这个echo $?返回值判断你这个程序运行是否ok。
例子:
如果你用脚本 a 调用脚本b ,要在a中判断b是否正常返回,就是根据 exit 0 or 1 来识别。

#!/bin/sh
SYSTEM=`uname -s` # 使用反引号获取操作系统类型
#使用$(uname -s)效果一样

if [ $SYSTEM = "Linux" ] ; then # 如果是linux话输出linux字符串
echo "Linux"
elif [ $SYSTEM = "FreeBSD" ] ; then 
echo "FreeBSD"
elif [ $SYSTEM = "Solaris" ] ; then
echo "Solaris"
else
echo "What?"
fi # 判断结束,以fi结尾

[]里面的条件判断。说明如下:

8.4.1 字符串判断
语句 作用
str1 = str2 当两个串有相同内容、长度时为真
str1 != str2 当串str1和str2不等时为真
-n str1 当串的长度大于0时为真(串非空)
-z str1 当串的长度为0时为真(空串)
8.4.2 数字的判断

int1 -eq int2   两数相等为真

注意:也可以使用"==",但是如果if [ 判断条件 ]中 == 左右没有空格,不会报错并且按照True来执行,所以不建议使用"=="
语句 作用
int1 -ne int2 两数不等为真
int1 -gt int2 int1大于int2为真
int1 -ge int2 int1大于等于int2为真
int1 -lt int2 int1小于int2为真
int1 -le int2 int1小于等于int2为真
8.4.3 复杂逻辑判断
语句 作用
-a
-o
!
8.4.4 文件相关的常用if判断条件语句,完整部分在8.5.5
语句 作用
-e filename 如果 filename存在,则为真
-r file 用户可读为真
-w file 用户可写为真
-x file 用户可执行为真
-f file 文件为常规文件为真
-d file 文件为目录为真
-c file 文件为字符特殊文件为真
-b file 文件为块特殊文件为真
-s file 文件大小非0时为真
-t file 当文件描述符(默认为1)指定的设备为终端时为真
-L filename 如果 filename为符号链接,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
8.4.5 if 语法参数

[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。

[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。

[ -d FILE ] 如果 FILE 存在且是一个目录则为真。

[ -e FILE ] 如果 FILE 存在则为真。

[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。

[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。

[ -h FILE ] 如果 FILE 存在且是一个符号连接则为真。

[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。

[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。

[ -r FILE ] 如果 FILE 存在且是可读的则为真。

[ -s FILE ] 如果 FILE 存在且大小不为0则为真。

[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。

[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。

[ -w FILE ] 如果 FILE 如果 FILE 存在且是可写的则为真。

[ -x FILE ] 如果 FILE 存在且是可执行的则为真。

[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。

[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。

[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。

[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。

[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。

[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1FILE2 does not则为真。

exists and [ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。

[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。

[ -o OPTIONNAME ] 如果 shell选项 “OPTIONNAME” 开启则为真。

[ -z STRING ] “STRING” 的长度为零则为真。

[ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。

[ STRING1 == STRING2 ] 如果2个字符串相同。 “=” may be used instead of “==” for strict POSIX compliance则为真。

[ STRING1 != STRING2 ] 如果字符串不相等则为真。

[ STRING1 < STRING2 ] 如果 “STRING1” sorts before “STRING2” lexicographically in the current locale则为真。

[ STRING1 > STRING2 ] 如果 “STRING1” sorts after “STRING2” lexicographically in the current locale则为真。

[ ARG1 OP ARG2 ] “OP” is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if “ARG1” is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to “ARG2”, respectively. “ARG1” and “ARG2”
are integers. 表达式可以借以下操作符组合起来,以降序列出:listed in decreasing order of precedence: 表 7.2. 组合表达式操作 效果

[ ! EXPR ] 如果 EXPR 是false则为真。

[ ( EXPR ) ] 返回 EXPR的值。这样可以用来忽略正常的操作符优先级。

[ EXPR1 -a EXPR2 ] 如果 EXPR1 and EXPR2 全真则为真。

[ EXPR1 -o EXPR2 ] 如果 EXPR1 或者 EXPR2 为真则为真。 [ (或作 test) 内建命令对条件表达式使用一系列基于参数数量的规则来求值。更多关于这个主题的信息可以在Bash文档中查找。就像if 使用fi 来结束一样,在条件列完之后必须用">"来结束。

8.5 函数

#!/bin/bash
funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"

结果:

这个函数会对输入的两个数字进行相加运算...
输入第一个数字: 
1
输入第二个数字: 
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 !

函数返回值在调用该函数后通过 $? 来获得。

注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

#!/bin/bash
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

以上摘自https://www.runoob.com/linux/linux-shell-func.html
实际使用时,不建议在函数中这样取参数,
可以使用shift,隔开使用各个参数,只输入需要使用的参数,这样每个参数使用过就会丢弃,永远用$1去调用参数就行了,以上代码可以改成:

#!/bin/bash
funWithParam(){
    echo "第一个参数为 $1 !"
shift
    echo "第二个参数为 $1 !"
shift
    echo "第三个参数为 $1 !"
shift
    echo "第四个参数为 $1 !"
shift
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 

结果:
第一个参数为 1 !
第二个参数为 2 !
第三个参数为 3 !
第四个参数为 4 !
参数总数有 0 个!
作为一个字符串输出所有参数  !

8.6 shell判断文件夹是否存在

#如果文件夹不存在,创建文件夹
if [ ! -d "/myfolder" ]; then
  mkdir /myfolder
fi

#shell判断文件,目录是否存在或者具有权限

folder="/var/www/"
file="/var/www/log"

# -x 参数判断 $folder 是否存在并且是否具有可执行权限
if [ ! -x "$folder"]; then
  mkdir "$folder"
fi

# -d 参数判断文件夹是否存在
if [ ! -d "$folder"]; then
  mkdir "$folder"
fi

# -f 参数判断文件是否为常规文件
if [ ! -f "$file" ]; then
  touch "$file"
fi

# -n 判断一个变量是否有值
if [ ! -n "$var" ]; then
  echo "$var is empty"
  exit 0
fi

8.7 shuf

按行打乱文件
shuf test1.txt
把打乱的文件结果写入到output.txt
touch output.txt
shuf test1.txt -o output.txt.
显示文件中的任意5行
shuf -n 5 test1.txt
打乱数据再重定向到新文件中
shuf train.data > labeled.data.shuf

8.8 split

    split支持自定义输出文件大小和输出文件行数两种模式,此外还可以定义每一行最大的值。

         -l   按输出文件行数 : split -l 200 input_file out_file
         -b  按输出文件大小 : split -b 200 input_file out_file(注意-b后边跟的数字需要换算成字节数)

        注:out_file为输出文件的前缀
        另外,还有 -d 和 -a 两个选项:

        -d   如果加上-d则后缀为数字,不加则默认为字母
        -a   默认为2,意思是后缀的位数,这个是根据你分出来的文件个数决定的

9. 正则表达式(grep,awk,sed)

9.1 grep

g/re/p(globally search a regular expression and print),使用正则表示式进行全局查找并打印。

$ grep [-acinv] [--color=auto] 搜寻字符串 filename
-c : 统计个数
-i : 忽略大小写
-n : 输出行号
-v : 反向选择,也就是显示出没有 搜寻字符串 内容的那一行
--color=auto :找到的关键字加颜色显示

示例:把含有 the 字符串的行提取出来(注意默认会有 --color=auto 选项,因此以下内容在 Linux 中有颜色显示 the
字符串)

cat $ cat regular_express.txt 
reference:
https://www.cnblogs.com/huai371720876/p/4561195.html
http://blog.csdn.net/feibendexiaoma/article/details/73739279
https://www.runoob.com/linux/linux-shell-echo.html
http://c.biancheng.net/view/944.html
https://blog.csdn.net/bible_reader/article/details/81776896
google is the best tools for search keyword
$ grep -n 'the' regular_express.txt
7:google is the best tools for search keyword

實際使用,
例如:查看所有python關鍵字的進程
ps -ef|grep python
然后杀死某个进程kill -s 9 27956 -s 9 代表尽快结束,27956是进程ID
其他例子:

在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。
grep test *file 

以递归的方式查找符合条件的文件。例如,查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串"update"的文件,并打印出该字符串所在行的内容
grep -r update /etc/acpi 

反向查找。前面各个例子是查找并打印出符合条件的行,通过"-v"参数可以打印出不符合条件行的内容。
查找文件名中包含 test 的文件中不包含test 的行
grep -v test *test*

9.2 printf

用于格式化输出。它不属于管道命令,在给 printf 传数据时需要使用 $( ) 形式。

9.3 awk

是由 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 创造,awk 这个名字就是这三个创始人名字的首字母。
awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk 每次处理一行,处理的最小单位是字段,每个字段的命名方式为:$n,n 为字段号,从 1 开始,$0 表示一整
行。
示例:取出最近五个登录用户的用户名和 IP

$ last -n 5
liangjix pts/0        10.3.140.22      Tue May 21 10:44   still logged in   
liangjix pts/3        10.3.140.22      Mon May 20 11:37 - 10:44  (23:06)    
mzyunwei pts/3        10.3.135.249     Mon May 20 11:30 - 11:31  (00:00)    
wangyao  pts/2        10.3.140.22      Mon May 20 09:47   still logged in   
wangyao  pts/2        10.3.140.22      Mon May 20 09:43 - 09:46  (00:02)    

取出一字段和三字段

$ last -n 5 | awk '{print $1 "\t" $3}'
liangjix    10.3.140.22
liangjix    10.3.140.22
mzyunwei    10.3.135.249
wangyao 10.3.140.22
wangyao 10.3.140.22

可以根据字段的某些条件进行匹配,例如匹配字段小于某个值的那一行数据。
$ awk '条件类型 1 {动作 1} 条件类型 2 {动作 2} ...' filename
示例:/etc/passwd 文件第三个字段为 UID,对 UID 小于 10 的数据进行处理。

$ cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'
root 0
bin 1
daemon 2
awk 变量:
变量名称 代表意义
NF 每一行拥有的字段总数
NR 目前所处理的是第几行数据,每行的记录号,多文件记录递增
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
FS 目前的分隔字符,默认是空格键
$0 表示整个当前行
$1 每行第一个字段
\t 制表符
\n 换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
II 逻辑或
+ 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名
OFS 输出字段分隔符, 默认也是空格,可以改为制表符等
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]' 定义三个分隔符

示例:显示正在处理的行号以及每一行有多少字段

$ last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF}'
liangjix     lines: 1    columns: 10
liangjix     lines: 2    columns: 10
mzyunwei     lines: 3    columns: 10
wangyao  lines: 4    columns: 10
wangyao  lines: 5    columns: 10
awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
 [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
'  '   引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
//     匹配代码块,可以是字符串或正则表达式
{}     命令代码块,包含一条或多条命令
;    多条命令使用分号分隔
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
用':'分割,输出第一列
$ cat /etc/passwd |awk  -F ':'  '{print $1}'
root
bin
daemon
adm
lp
sync
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
$ cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}'
root    /bin/bash
bin /sbin/nologin
daemon  /sbin/nologin
adm /sbin/nologin
lp  /sbin/nologin
sync    /bin/sync

小例子
数据集 data文件
求第二列所有值的和:

cat data | awk '{sum+=$2}END(print sum)'

把第一列相同的值和第二列相加

cat data | awk '{a[$1]+=$2}END{for i in a)printf "%s %d\n",i,a[i]}'

把第一列相同的值和第二列相加,并按照降序排列。
降序排列:sort -n -r -k2(第二列的值)
直接按照第二列降序排列
sort -n -r -k2 data

cat data | awk '{a[$1]+=$2}END{for i in a)printf "%s %d\n",i,a[i]}' | sort -n -r -k2

9.4. sed

摘自:https://www.cnblogs.com/wangqiguo/p/6718512.html

sed [选项] [动作]

选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。

function:
a :新增行, a 的后面可以是字串,而这些字串会在新的一行出现(目前的下一行)
c :取代行, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d :删除行,因为是删除,所以 d 后面通常不接任何参数,直接删除地址表示的行;
i :插入行, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
例如:
sed -n 1,20p labeled.data.shuf > train.data
sed查询某个时间段的内容
sed -n '/2018-05-23 18:10/,/2018-05-23 18:11/p' log_info.log
s :替换,可以直接进行替换的工作,通常这个 s 的动作可以搭配正规表示法,例如 1,20s/old/new/g 一般是替换符合条件的字符串而不是整行

一般function的前面会有一个地址的限制,例如 [地址]function,表示我们的动作要操作的行。下面我们通过具体的例子直观的看看sed的使用方法。

删除行
test.txt 内容如下
11 aa
22 bb
33 cc
23 dd
55 2e

sed '1,2d' test.xx

输出:
33 cc
23 dd
55 2e

其中1,2d中的d表示删除,而d前面的表示删除的行的地址,而1,2表示一个地址范围,也就是删除第1行和第2行。
地址范围的表示一般是  m,n 表示对m和n行之间的所有行进行操作,也包含第m行和第n行。
sed的地址寻址中可以使用$表示最后一行,例如m,$ 表示对m行以及其后面的所有行进行操作,包括最后一样。
m,$d就是删除m行以及其后面的所有行内容。
当然我们还可以对某一行进行操作,例如2d表示仅仅删除第2行。
除了使用数字范围 m,n 表示多行区间,以及m表示单行以外,我们还可以使用正则表达式选出符合条件的行,并对这些行进行操作,同样的是上面的文件:

sed '/2/d' test.txt

输出:
11 aa
33 cc

上面的命令中 /2/ 是一个正则表达式,在sed中正则表达式是写在 /.../ 两个斜杠中间的,这个正则的意思是寻找所有包含2的行,
执行相应的操作,也就是删除所有包含2的行,如果我们只想删除以2开头的行呢,只需要修改一下正则表达式就可以了:

sed '/^2/d' test.txt

输出:
11 aa
33 cc
55 2e
新增行
sed '1a hello world' test.txt

输出:
11 aa
hello world
22 bb
33 cc
23 dd
55 2e

其中a命令表示在指定行的后面附加一行,1a则是在第一行的后面添加一行,
添加的内容就是a后面的内容,如果a的前面没有地址限定则在所有行的后面都会添加指定的字符串
sed '1i hello world' test.txt

输出:
hello world
11 aa
22 bb
33 cc
23 dd
55 2e

命令i表示在指定的行的前面插入一行,插入的内容为其后面的字符串
替换行
`sed '1c hello world' test.txt`

输出:
hello world
22 bb
33 cc
23 dd
55 2e

命令c会替换指定的行的所有内容,替换成其后面的字符串,所有的新增,删除,替换行,
这些命令前面的地址修饰都可以指定地址空间,也都可以使用正则表达式,命令会应用在选出的符合地址条件的所有行上面,例如:

`sed '/^2/c hello world' test.txt`

输出:
11 aa
hello world
33 cc
hello world
55 2e


替换以2开头的行,其内容是c命令后面的字符串
替换部分字符串而不是整行
sed中除了上面的命令是针对整行进行操作的之外,还提供一个替换命令,
该命令对某一行中的部分字符串进行操作,下面举一个简单的例子,还是同样的文本内容,执行下面的命令:

`sed 's/aa/AA/' test.txt`

输出:
11 AA
22 bb
33 cc
23 dd
55 2e

我们这里说的就是s命令,执行的结果是我们文件中的 aa 被替换成 AA ,我们看一下s命令后面接的是3个斜杠分隔的两串字符串,其含义是   s/待替换的字符串/新字符串/ 也就是说使用后面的 AA 替换文件中出现的前面的 aa 。实际上这里的替换仅仅替换每一行遇到的第一个aa,我们修改一下文件的内容:

//test.txt
11 aa
22 bb
33 cc
23 dd
55 2e
66 aaff ccaa
zz ggaa

`sed 's/aa/AA/' test.txt`

输出:
11 AA
22 bb
33 cc
23 dd
55 2e
66 AAff ccaa
zz ggAA

可以看到第6行的ccaa中的aa是没有被替换的,也就是说此时仅仅替换了每一行搜索到的第一个aa字符串进行操作,那么如果要对一行里面的所有的符合条件的字符串都做替换操作呢,我们可以使用参数g,例如修改命令如下:

`sed 's/aa/AA/g' test.txt`

输出:
11 AA
22 bb
33 cc
23 dd
55 2e
66 AAff ccAA
zz ggAA

在最后一个斜杠后面加上g选项之后,表示进行全局替换,也就是说一行中所有符合条件的旧字符串都会被替换成新字符串,而不仅仅是第一个。与其他针对行的操作一样,s命令也可以进行地址选择,其地址使用方法与我们之前的一样,也就是在s的前面加上地址空间限定,例如:

`sed '1s/aa/AA/g' test.txt`

输出:
11 AA
22 bb
33 cc
23 dd
55 2e
66 aaff ccaa
zz ggaa

可以看到仅仅对第一行进行了替换操作,其他的地址限定方法同样也是可以使用的,我们可以使用m,n的限定,例如:

`sed '5,$s/aa/AA/g' test.txt`

输出:
11 aa
22 bb
33 cc
23 dd
55 2e
66 AAff ccAA
zz ggAA

表示对第5行直到文件末尾的所有行进行搜索替换操作,同样s命令的地址限定也支持使用正则表达式限定符合条件的行,然后在这些行中进行字符串的搜索替换操作,例如:

`sed '/^[0-9]/s/aa/AA/g' test.txt`

输出:
11 AA
22 bb
33 cc
23 dd
55 2e
66 AAff ccAA
zz ggaa

我们在s命令前面添加了 /^[0-9]/ 这个修饰,该正则表达式表示对所有以数字开头的行,执行s操作

另外一个要说明的是  s/待替换的字符串/新字符串/ 这种格式中 / 作为分隔符并不是一定的,
当使用s命令时候,我们可以使用别的分隔符,实际上s后面紧接着的字符就是分隔符,所以不一定是 / 符号。例如:

`echo 'aabbccaadd' | sed s#aa#AA#g`

输出:
AAbbccAAdd

这里s命令后面跟着的#符号被当作分隔符了
搜索并输出行内容
sed还提供一个p命令用于搜索符合条件的行,并输出该行的内容,而不做其他的任何修改,例如:

//test.txt
11 aa
22 bb
33 cc
23 dd

`sed '2p' test.txt`

输出:
11 aa
22 bb
22 bb
33 cc
23 dd

可以看到第二行被输出来了,但是sed好像将文件的所有内容输出了一遍,而第2行则多输出了一次,
实际上sed默认情况下是会将所有标准输入的数据又重新输出到标准输出的,
我们可以加上 -n 选项让sed仅仅是输出经过处理之后的那些行,而不是输出之前从标准输入中获取到的所有行内容,例如:

`sed -n '2p' test.txt`

输出:
22 bb

这样仅仅会输出p命令的处理结果了,-n 选项一般是与p命令联合使用的,其他的增加,删除,替换行的命令是不需要 -n 选项的
将修改应用到文件中
我们之前做的所有实验,实际上都没有修改test.txt文件的内容,也就是说我们看到的修改结果仅仅输出到控制台上,而文件test.txt的内容是没有修改的,我们可以使用 -i 选项告诉sed直接修改文件的内容,而不是将修改结果输出到终端上,例如:

`sed -i '2d' test.txt `

命令运行之后,我们发现test.txt的第2行没有了
sed正则中的元字符

我们知道sed中的命令前面可以使用地址范围进行限制,表示对文件的某些符合条件的行执行相应的操作,其中我们可以使用正则表达式选出要操作的行,而sed中正则的语法可能与我们其他命令的正则语法有一些不同,这里我们有必要列出sed中常用的正则元字符:

$ 表示行尾 
^ 表示行首
[a-z0-9]表示字符范围
[^]表示除了字符集中的字符以外的字符 

sed的正则中  \(\)  和 \{m,n\} 需要转义 
. 表示任意字符  
* 表示零个或者多个  
\+ 一次或多次  
\? 零次或一次    
\| 表示或语法

9.5 cut

Linux cut命令用于显示每行从开头算起 num1 到 num2 的文字。

语法:

cut  [-bn] [file]
cut [-c] [file]
cut [-df] [file]

使用说明:
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。

参数:

-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的
范围之内,该字符将被写出;否则,该字符将被排除
--complement:补足被选择的字节、字符或字段;
--out-delimiter=<字段分隔符>:指定输出内容是的字段分割符;

实例
当你执行who命令时,会输出类似如下的内容:

$ who
rocrocket :0           2009-01-08 11:07
rocrocket pts/0        2009-01-08 11:23 (:0.0)
rocrocket pts/1        2009-01-08 14:15 (:0.0)
如果我们想提取每一行的第3个字节,就这样:

$ who|cut -b 3
c
c

实例
who|cut -d "/" -f1

实例
学生报表信息:
$ cat test.txt
No Name Mark Percent
01 tom 69 91
02 jack 71 87
03 alex 68 98

使用 -f 选项提取指定字段:
cut -d " " -f1 test.txt
结果:
No
01
02
03
选取2和3列
cut -d " " -f2,3 test.txt
结果:
Name Mark
tom 69
jack 71
alex 68
选取1到3列
cut -d " " -f1-3 test.txt

9.6 paste

paste 命令用于合并文件的行。

语法
paste [-s][-d <间隔字符>][--help][--version][文件...]

参数:
-d<间隔字符>或--delimiters=<间隔字符>  用指定的间隔字符取代跳格字符。
-s或--serial  串列进行而非平行处理。
--help  在线帮助。
--version  显示帮助信息。
[文件…] 指定操作的文件路径

$ cat test.txt 
No Name Mark Percent
01 tom 69 91
02 jack 71 87
03 alex 68 98

cat test1.txt 
No Name Mark Percent
011 tom1 691 911
021 jack1 711 871
031 alex1 681 981

按照"|"拼接
$ paste -d "|" test.txt test1.txt
No Name Mark Percent|No Name Mark Percent
01 tom 69 91|011 tom1 691 911
02 jack 71 87|021 jack1 711 871
03 alex 68 98|031 alex1 681 981
按照空格拼接
$ paste -d " " test.txt test1.txt
No Name Mark Percent No Name Mark Percent
01 tom 69 91 011 tom1 691 911
02 jack 71 87 021 jack1 711 871
03 alex 68 98 031 alex1 681 981
合并多个文件时,可以使用多个分隔符
$ paste -d ",;" test.txt test1.txt test2.txt
No Name Mark Percent,No Name Mark Percent;No Name Mark Percent
01 tom 69 91,011 tom1 691 911;012 tom2 692 912
02 jack 71 87,021 jack1 711 871;022 jack2 712 872
03 alex 68 98,031 alex1 681 981;032 alex2 682 982
使用 -s 选项,paste 命令可以顺序地合并文件,即它顺序地将每个文件中的所有行的内容合并为一行,由此每个文件的内容被合并为单一的一行:
$ paste -s  test.txt test1.txt test2.txt
No Name Mark Percent    01 tom 69 91    02 jack 71 87   03 alex 68 98
No Name Mark Percent    011 tom1 691 911    021 jack1 711 871   031 alex1 681 981
No Name Mark Percent    012 tom2 692 912    022 jack2 712 872   032 alex2 682 982

$ paste -d"|" -s  test.txt test1.txt test2.txt
No Name Mark Percent|01 tom 69 91|02 jack 71 87|03 alex 68 98
No Name Mark Percent|011 tom1 691 911|021 jack1 711 871|031 alex1 681 981
No Name Mark Percent|012 tom2 692 912|022 jack2 712 872|032 alex2 682 982

12. 快捷键

快捷键 作 用
Ctrl+A 把光标移动到命令行开头。如果我们输入的命令过长,则在想要把光标移动到命令行开头时使用
Ctrl+E 把光标移动到命令行结尾
Ctrl+C 强制中止当前的命令
Ctrl+L 淸屏,相当于 clear 命令
Ctrl+U 刪除或剪切光标之前的命令。假设输入了一行很长的命令,无须使用退格键一个一个字符地刪除, 使用这个快捷键会更加方便
Ctrl+K 删除或剪切光标之后的内容
Ctrl+Y 粘贴 Ctrl+U 或 Ctrl+K 剪切的内容
Ctrl+R 在历史命令中搜索,按下 Ctrl+R 组合键之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索
Ctrl+D 退出当前终端
Ctrl+Z 暂停,并放入后台。这个快捷键涉及工作管理的内容,我们会在后续中详细介绍
Ctrl+S 暂停屏幕输出
Ctrl+Q 恢复屏幕输出

Reference:

https://www.cnblogs.com/wangqiguo/p/6718512.html
https://www.cnblogs.com/huai371720876/p/4561195.html
http://blog.csdn.net/feibendexiaoma/article/details/73739279
https://www.runoob.com/linux/linux-shell-echo.html
http://c.biancheng.net/view/944.html
https://blog.csdn.net/bible_reader/article/details/81776896

你可能感兴趣的:(常用的linux命令以及常用shell语句(基于ubuntu16&MACBOOK))