Shell 编程常用工具及函数

目录

 

一、Sed

什么是  sed ?

sed 的处理过程

定址

Sed中的常用选项:

Sed 中常用的命令

Sed中的修饰符:

Sed 的正则匹配

Sed 的不常用命令

 二、grep

(1)grep常用的参数:

(2)grep 中常用的RE

(3)例子

用于 egrep 和 grep -E 的元字符扩展集

egrep

fgrep

三、awk

awk格式

awk指令结构:

工作方式:

awk中自定义变量

awk 命令内置的一些特殊变量:

awk中的一些特殊符号:

awk的选项

-F 选项

-v 选项:

Print 说明:

awk 对行的条件过滤

awk 对行的正则过滤

awk中的 if 语句

四:bc

五:系统函数 read

六:系统函数 basename、dirname

1)basename基本语法:

2)dirname基本语法

七:xargs

命令结构:

常用参数:

对输入数据的处理

如何将参数添加到命令上

其它选项

八:cut

1、cut基本语法:

九:sort


一、Sed

 
在编写 shell 脚本的过程中,我们经常会使用到 sed
 

什么是  sed ?

sed 是一种在线编辑器,它一次处理一行内容。sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。
 

sed 的处理过程

sed 编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先 sed 把当前正在处理的行保存在一个临时缓冲区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed 每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed 便结束运行。    
前面说到 sed 不会修改文件,那么现在我们可以知道是为什么了,是因为 sed 把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。
 

定址

在使用 sed 的过程中,我们经常会听到“定址”,那什么是“定址”呢?
定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed 将处理输入文件的所有行。
 

Sed中的常用选项:

-n :静默模式,取消模式空间中内容的自动打印
地址是一个数字,则表示行号;是“$”符号,则表示最后一行。
地址是逗号分隔的,那么需要处理的地址是这两行之间的范围(包括这两行在内),范围可以用数字、正则表达式、或两者的组合表示。

$ sed -n '3p' filename  #只打印第三行

$ sed -n '$p' filename  #只打印最后一行

$ sed -n '100,200p' filename # 只打印文件的第100至200行 

$ sed  '/My/, /You/d' a.txt  # 删除包含"My"的行到包含"You"的行之间的行(包括匹配行)

$ sed   '/My/,10d' a.txt    # 删除包含 ‘My’的行到第十行的内容(包括匹配行和第10行)

-i :直接修改原文件

$ sed -i 's/tom/mick/' `grep -rl "tom" ./test`
将当前 test 目录(以及子目录)中,包含 “tom” 的文件,每行的第一个tom字符串替换为mick
$ sed -i  's/tom/mick/g'  a.txt   
将文件 a.txt 中的 tom 改为 mick
 
-e : 可以同时执行多个脚本(-e script1 -e script2),一般用于按照先后顺序进行处理的逻辑
$ sed -e "2d" -e "s/a/b/g" filename  
删除文件的第二行,并把文件中所有的 a 替换为 b
 
补充:
我如果要删除 a.txt 前两行中包含/aa/的行要怎么办呢?
与 -e 的“并列” 关系不同,这次我要处理的数据是“前两行” 与 “包含aa”这两个条件的交集!
为了完成这个需求,首先、我们这样使用 d 命令行不行呢?
$ sed '1,2/aa/d' a.txt
char 4 :unknown command: "/"
$ sed '1,2d/aa/' a.txt
char 5 : extra characters after command
此时我们需要使用到 “{}”
$ sed '1,2{/aa/d;}' a.txt 

-r : 使用扩展的正则表达式

扩展后有如下不同:

    组处理 \(pattern\) 可以直接写成 (pattern)

    \{1,\} 可以直接写成 {1,}

    \+ 可以直接写成 +

    \? 可以直接写成 ?

Sed 中常用的命令

s:查找并替换(默认只替换每行中第一次被匹配到的字符串)
紧跟在 s 命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为 “/ ”,但可以改变。无论什么字符(换行符、反斜线、a、i、p等命令字符除外),只要紧跟 s 命令,就成了新的串分隔符。

$ cat a.txt

aabb

aabb

aaaabb

aabb

$ sed '1,3s/aa/oo/' a.txt

oobb

oobb

ooaabb

aabb

$ sed 'smaamoom' a.txt    # m 变成了分隔符

oobb

oobb

ooaabb

oobb

$ sed -n '1,20s/my$/you/gp' filename

匹配1到20行中以my结尾的行,将所有行尾的my 替换为 you ,将处理后的行打印出来。

p:命令 p 用于显示模式空间的内容 

$  cat a.txt
1111
2222
3333
4444
$ sed  '1,2p' f.txt
1111
1111
2222
2222
3333
4444
注:不使用选项 -n 的情况下,sed 会默认打印模式空间中的内容,如果再使用 p 命令的情况下,你会发现指定的行被打印了2次

d :删除符合条件的行

注意:d 命令只能放到筛选条件的后面

$ sed "/a/d" a.txt  # 删除文件中包含 a 的行。

$ sed  "/^$/d"  a.txt     # 删除文件中的所有空行

$ sed  'd/aa/' a.txt

char 2: extra characters after command

a \string :在指定的行后面追加新的行,内容为 string

有两种写法:

$ cat a.txt

aaa

bbb

ccc

$ sed '2a newline' a.txt

aaa

bbb

newline

ccc

$ sed '2a\newline'  a.txt

aaa

bbb

newline

ccc

i\string :在指定的行前面添加新行,内容为 string

$ cat a.txt

aaa

bbb

ccc

$ sed '2i before' a.txt

aaa

before

bbb

ccc

$ sed '/bbb/i\before' a.txt

aaa

before

bbb

ccc

$ sed '1,2i before' a.txt

before

aaa

before

bbb

ccc

对所选行以外的所有行应用命令

$ cat a.txt

1

2

3

$ sed  '2!ia' a.txt

a

1

2

a

3

$ sed  '1,2!ia' a.txt

1

2

a

3

$ sed  '1,2!d' a.txt

1

2

r FILE:将指定的文件的内容添加至符合条件的行后面

$ cat f.txt

11

22

33

$ sed  '/aaa/r f.txt' a.txt

aaa

11

22

33

bbb

ccc

w FILE:将地址指定范围内的内容另存至指定的文件(文件不存在会自动创建)

$ cat a.txt
111
222
333
$ sed '1,2w f.txt' a.txt
111
222
333
$ cat f.txt
111
222
$ sed '/333/w f.txt' a.txt
111
222
333
$ cat f.txt
333
注意:多次对一个文件进行写操作是以覆盖的形式进行的
$ sed  '1,4w/root/f.txt'   a.txt  # 将1至4行的内容写入到 /root/f.txt 中   
$ sed  '1,4w ../f.txt'  a.txt        # 将1至4行的内容写入到当前目录的上级目录的 f.txt

Sed中的修饰符:

g:全局替换
i:忽略字符大小写

$ cat a.txt

abca

ACCA

AACA

$ sed 's/a/o/' a.txt

obca

ACCA

AACA

$ sed 's/a/o/g' a.txt

obco

ACCA

AACA

$ sed 's/a/o/gi' a.txt

obco

oCCo

ooCo 

& :保存查找串以便在替换串中引用

$ cat a.txt

my name is

$ sed 's/my/**&**' a.txt

**my** name is

Sed 的正则匹配

 
1)sed 的正则表达式放在“//”之间
$ sed 's/^#//g' /etc/inittab  # 删除 /etc/inittab 文件中开头的 # 号
 
$ sed  's/\(id:\)[0-9]\(:def\)/\15\2/g' a.txt  # 将“id:3:def”中的3替换为5
注:这里面用了 2 种正则结构
\( \) : 将匹配的结构进行分组保存,后面可以直接使用 " \1" 来代表前面匹配到的值
[0-9] :匹配一个数字

2)以行为匹配对象(^、$)

以单词为匹配对象(\<word 、 word\>)

$ cat a.txt

am i 

ami nik

i am

i nicam

mickaml

$ sed -n '/^am/p' a.txt   # 以 am 开头的行

am i

ami nik

$ sed -n '/am$/p' a.txt   # 以am 结尾的行

i am

i nicam

$ sed -n '/\<am/p' a.txt  # 行中包含以 am 开头的单词

am i

ami nik

i am

$ sed -n '/am\>/p' a.txt  # 行中包含以 am 结尾的单词

am i

i am

i nicam

3)空白符

在 sed 的正则表达式中用 [[:space:]] 表示空白符(一个 Tab 或者 一个空格)

在 pattern 中空格可以直接匹配,但如果要匹配 Tab 就需要使用 [[:space:]]

$ cat a.txt  
a b c          # ab之间一个空格
a  b c         # ab之间两个空格
a    b c       # ab之间一个 Tab
a        b c   # ab之间两个 Tab
$ sed  's/a *b/mm' a.txt    # 替换,行中包含的结构( a 与 b 之间有零个或多个空格)为 mm
mm c
mm c
a    b c
a        b c
$ sed  's/[[:space:]]//g' a.txt  # 删除行中的空白符
abc
abc
abc
abc
4)“ \ ” 在正则中的转义

$ cat a.txt

aal

all

a*ll

$ sed  's/a\*/o/' a.txt

aal

all

oll

$ sed  's/a*/o' a.txt

ol

oll

o*ll

Sed 的不常用命令

n 命令

sed 使用该命令获取输入文件的下一行,并将其读入到模式缓冲区中,任何 sed 命令都将应用到匹配行紧接着的下一行上。

注:如果需要对匹配行使用多条命令,或者需要在某个地址范围内嵌套地址,就必须用花括号将命令括起来,每行只写一条命令,或者用分号分割同一行中的多条命令

$ cat a.txt

testing

aa    bb

aa    cc

$ sed '/testing/{n;s/aa/oo/;}' a.txt

testing

oo    bb

aa    cc

$ sed -n '/testing/{n;s/aa/oo/;p}' a.txt

oo    bb 

--------------- 一些特殊用法 ---------------

$ cat a.txt

1

2

krootk

$ sed -n '/root/{=;p}' a.txt   # 打印包含 root 的行及行号

3

krootk

$ sed -n '/root/{n;d}' filename     # 将包含 root 行的下一行删除

$ sed -n '/root/{N;d}' filename     # 删除 root 行以及下一行

q 命令

q此命令将导致 sed 程序退出,不再进行其它的处理

$ cat a.txt
cc
aa bb
aabb
aaa b
$ sed 's/aa/oo/' a.txt   
cc
oo bb
oobb
ooa b
$ sed 's/aa/oo/q' a.txt   # 这种写法是错的,因为 q 是个命令,而不是修饰符。
 
$ sed '{s/aa/oo/;q}' a.txt
cc
只输出一个 cc 就退出了,而不是找到第一个 aa 做替换之后退出
sed 从 a.txt 读入第一行,执行 { } 里面的内容,遇到 q 命令整个 sed 就退出了。

y:将字符按照一对一的方式从左到右进行转换。这个命令太局限常用的是 s 命令 

$ cat a.txt
abc
ABC
def
$ sed '1,2y/abc/XYZ' a.txt
XYZ
ABC
def
$ sed '1,2y/abc/WXYZ/' a.txt
前后字符数量不一致,会报错

 二、grep

(1)grep常用的参数:

  • -v:逆反模式,只输出“不含” RE 字符串的句子

  • -r:递归模式,可同时处理所有层级子目录里的文件

  • -q:静默模式。不输出任何结果(stderr除外,常用以获取 return value,符合 RE 则为true,反之为false)

  • -i:忽略大小写

  • -w :整词比对(精确匹配)

  • -n:同时输出行号

  • -c:只输出符合比对的行数,不显示匹配的内容

  • -l:只输出符合比对的文件名称(小写的L)

  • -E :切换为 egrep。

  • -?(数字) :同时显示匹配行上下的 ?行,如 grep -2 pattern filename 同时显示匹配行的上2行、下2行。

  • -o:show only the part of a line matching PATTERN

(2)grep 中常用的RE

^ :锚定行的开始,如:'^grep' 匹配所有以 grep 开头的行。

$:锚定行的结束,如:'grep$' 匹配所有以 grep 结尾的行。

. : 匹配一个非换行符的任意字符,如:'gr.p'匹配 gr 后接一个任意字符,然后是 b

*:匹配零个或多个先前字符,如:' *grep' 匹配所有一个或多个空格后紧跟grep的行。.*一起用代表任意字符。

[]:匹配一个指定范围内的字符,如:'[Gg]rep' 匹配 Grep 和 grep。

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

 

x\{m\} :重复字符 x ,m次,

如:‘p\{5\}’匹配包含5个p的行。

grep '\(grep\)\{3\}'  gcx.txt 匹配包含3个连续 grep的字符串

 

x\{m,\}:重复字符x,至少m次,如:'a\{4,\}' 匹配至少有4个a的行

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

\w:匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p' 匹配以G后跟零个或多个文字或数字字符,然后是p。

\W:是 \w 的反置形式,匹配非单词字符,如点号、句号等。

\b :单词锁定符,如:'\bgrep\b' 只匹配单词grep  

\(.. \) :标记匹配字符,如 '\(love\)',love被标记为1。

例:

$ grep 'w\(es\)t.*\1' aa

如果 west 被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个 es(\1),找到就显示该行。

如果用 egrep 或 grep -E ,就不用 “\”号进行转义,直接写成 'w(es)t.*\1' 就可以了。

(3)例子

-w 精确匹配

$ cat goface.txt

goface

gofaceme

$ grep 'goface' goface.txt

goface

gofaceme

$ grep -w 'goface' goface.txt

goface

-r  递归搜索查找指定目录下的所有文件(包括子目录),匹配你要查找的字符串

如果指定的目录下文件太多或含有大文件,可以使用以下参数对文件进行过滤:

--include=PATTERN

--exclude=PATTERN

grep magic /usr/src     # 显示 /usr/src 目录下的文件(不含子目录)包含magic的行

grep -r magic /usr/src  # 显示 /usr/src 目录下的文件(包含子目录)包含 magic 的行  

-o \ -r  \ -l

-e :执行多个pattern匹配

用于 egrep 和 grep -E 的元字符扩展集

 +:匹配一个或多个先前的字符

 ?:匹配0个或多个先前字符

 a|b|c :匹配 a 或 b 或 c

egrep

为 grep 扩充版本,改良了许多传统 grep 不能或不便的操作,比方说:

-grep 之下不支持  ? 与  + 这两种修饰字符,但 egrep 则可。

-grep 不支持 a|b 或 (abc|xyz)这类“或一”比对,但 egrep 则可

-grep 在处理 {n,m}时,需要用 \{  与 \} 处理,但 egrep 则不需。

fgrep

不作 RE 处理,表达式仅作一般字符串处理,所有meta均失去功能。 

三、awk

 

awk格式

awk [选项] '[条件]{指令}' 文件
前置命令 | awk [选项] '[条件]{指令}'
其中 “{}”代表一个命令代码块,包含一条或多条命令,命令之间用“ ; ” 分隔
 

awk指令结构:

    awk  'BEGIN{ state1 }[条件] {state2 } END{state3 }'  filename
注意条件要放在 BEGIN 语句块之后,
或者当单引号内没有BEGIN时,放在单引号之外:awk [条件] '{ }' filename  
 

工作方式

    1、执行 BEGIN 中的语句块
    2、从文件或stdin中读入一行,与条件进行匹配,不符合条件直接扔掉,如果符合条件开始执行 state2,重复这个过程,直到文件全部被读取完毕;
    3、执行 END 语句块
例:

$ cat a.txt

1

2

3

$ awk 'BEGIN{k1="v1" print k1}{print}END{print k1}' a.txt

v1

1

2

3

v1

awk中自定义变量

########  在 awk 语句块中定义变量  #######
$ echo | awk 'BEGIN{ sun=4 } { print sun } END{ print sun }'
4
4
$ echo | awk 'BEGIN{ print sun } { sun=4; print sun } END{ print sun }'
 
4
4
echo | awk 'BEGIN{ print sun } {print sun } END{sun=4;print sun}'
 
 
4
$ echo | awk -v sun=4 'BEGIN{ print sun } {print sun } END{ print sun }' # 使用 -v 参数设置内部变量。
4
4
4
###########  传递外部变量  ##########
$ var=100
$ echo | awk 'BEGIN{print "start", vara} {print vara } END{print "end",vara}' vara=$var
start
100
end 100
经测试:
BEGIN 命令块中取不到变量 vara!
vara=$var 只能放到最后

awk 命令内置的一些特殊变量:

    NR :表示已处理的行数,在处理过程中对应当前行号;

    NF :表示字段数量,在执行过程中对应当前行按照分隔符分割后的字段(field)数;

    $0 :执行过程中表示当前行的文本内容;可省略;

    $1 :第一个字段的文本内容;

    $2 :  第二个字段的文本内容;

    FILENAME:当前处理的文件名;

    ENVIRON:环境变量,用法:ENVIRON["变量名称"]

        bash 中常用的环境变量有:

            $HOME:当前用户家目录

            $PWD:当前工作目录

            $SHELL :默认的解释器

            $USER:当前登录用户

$ cat a.txt
a b c
a b c
$ awk '{print $2,$3}' a.txt
b c
b c
$ awk -F: '$1==ENVIRON["USER"]{print $3}' /etc/passwd
打印以 “ : ”分割后,第一个字段为当前shell用户名(echo "$USER")的行的第三个字段
$ awk '{print NF}' file  # 显示每行有几个字段
$ awk '{print $NF}' file  # 将每行的第 NF (最后) 一个字段打印出来

awk中的一些特殊符号:

    \t :制表符

    \n :换行符(可以用在 print 中 )

    ~: 匹配,与==相比不是精确比较(后面常跟正则)

    !~ :不匹配,不精确比较

    == : 等于,必须全部相等,精确比较

    != :不等于 ,精确比较

    && :逻辑与

    || :逻辑或

    + :匹配1次或多次

    ? : 匹配0次或一次

$ echo | awk 'END{print "A""\t""B" }' 

A    B

$ echo | awk 'END{print "A""\n""B" }'

A

B

awk的选项

-F 选项

使用 “ -F ”来设置分割符(默认为空格)

注:在使用 -F 指定一些特殊(shell 中的元字符)分隔符时,需要在分隔符前面加上 "\" 进行转义(如 :-F\")

-F'[:#/]'  :定义三个分隔符

例一:
$ awk -F: '{ print $NF }' /etc/passwd
以 “ : ” 为分隔符,将 passwd 中的每行进行分割,并打印每行分割后的最后一个字段。
例二:
假设文件(a.txt)中有如下内容:
"usage":"0.64%"
"usage":"0.84%"
以"分割可以NF=5
 
如果我想取出 0.84 可以这样操作
方法一:
sed -n '$p' a.txt | awk -F: '{ print $2}' | awk -F% '{ print $1 }' | awk -F\" '{ print $2}'
方法二:
awk -F'["%]' NR==2'{print $4}' a.txt
 
如果我进行如下操作又会得到什么结果呢?
awk -F\" '{print $1}'  a.txt   
答案是会得到两个空行
 
以“  进行切割会得到 5个字段
$ awk -F\" '{ print NF }' a.txt
5
5
 
以 " % 进行切割会得到 6 个字段
$ awk -F'["%]' '{print NF}' a.txt 
6  
6
注意:指定的分隔符里面有个 shell 中的元字符 " ,所以要在 ["%] 外面加上单引号 
 
以 : % 进行切割会得到3个字段
$ awk -F[:%] '{print NF} a.txt
3
3
 
以 " % 进行切割会得到7个字段 
$ awk -F'["%:]' '{print NF}' a.txt
7
7

-v 选项:

定义一个变量 
$ awk -F:  -v i=1 '{ print $3+1 } ' /etc/passwd

Print 说明

1、使用不带参数的 print 时,会打印当前行的所有内容

$ echo -e "line1\nline2" | awk 'BEGIN{ print "start"} { print } END{print "End"}'

line1

line2

2、print 以逗号分隔时,参数以空格定界

$ echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3}'

 v1 v2 v3

$ echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1 var2  var3}'

v1v2v3

3、使用双引号来指定 Print 参数之间的“拼接符”

$ echo | awk '{var1="v1"; var2="v2"; var3="v3";print var1"-"var2"-"var3;}'

v1-v2-v3

awk 对行的条件过滤

$ awk 'NR==1,NR==4 {print}' file    #将行号为[1,4]的行打印出来 

$ awk 'NR==5||NR==6{print}' file  #打印第5行和第6行

$ awk 'NR%2==1{print}' file   # 打印出奇数行

$ awk 'NR==2{print}' file   # 打印第二行

$ awk '$2!="xx"{print}' file    # 打印第二个字段不为 "xx" 的行

$ awk 'NF==3{print}' file  # 打印分割后只有三个字段的行

$ awk 'NF>=2{print}' file  # 打印分割后有2个以上字段的行

$ awk 'NF>=2&&$2!="pop"{print}' file  #打印分割后有2个以上字段,并且第二个字段不为“pop”的行。或关系用 “||”

awk 对行的正则过滤

awk的正则表达式与sed一样放在 “//” 之间

$ awk '/^ro/{print}' /etc/passwd  # 打印以 ro 开头的行
$ awk  '$2!~/bash$/{print $1,$2}' file    # 打印第二个字段不以 bash 结尾行的第一、第二个字段
$ awk '$2~/bash$/{print $1,$2}' file   # 打印第二列以 bash 结尾行的第一、第二字段
 
$ awk '!/mysql/{print $0}' /etc/passwd
打印不包含mysql的行
 
$ awk '!/mysql|oracle/{print}'  file
打印不包含mysql或oracle的行
 
awk -F: '/my/,/he/{print}' file  #区间匹配
打印从上往下第一个包含my的行至第一个包含he的行,包括边界

$ cat a.txt

bash

login bash

bash\>

$ awk 'BEGIN{x=0} /bash\\>/ {x++;print]END{print x}' a.txt

bash\>

1

经过测试 awk 的正则不支持 “\<”“\>” “\b”这三种单词定界符

awk中的 if 语句

必须用在 {}中,且内容用()括起来

$ awk -F: '{ if($1~/mail/) print $1}' file   #简写

$ awk -F: '{ if($1~/mail/) {print $1}}' file  #全写

$ awk -F: '{ if($3>100) {print $1} else {print $2}}' file

常见用法:

例一:

$ awk 'END{print NR}' a.txt   # 统计文件的行数(包括空行)

3

例二:

$ awk 'BEGIN{a=12.3; print a+12} '   # 计算器

24.3

例三:累加每一行的第二个字段(field)

$ cat a.txt

10a3    2k

2b    k9l

3c    2m

$ awk '{sum+=$2} END{print "=="; print sum }' a.txt

==

4

$ awk '{sum+=$1} END{print "=="; print sum }' a.txt

==

15

例四:统计当前目录下所有文件(不包含文件夹)的大小总和

$ ls -l | awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{ print "total size is",sum}'

四:bc

bash 中,默认的数据类型都是字符串类型,无法直接进行数值运算。

编写 shell 脚本的过程中我们经常使用 bc 对 浮点数进行处理

一:比较大小
if [ $(echo "4.4<4"|bc) -eq 1 ];then
echo "4.4<4"|bc  # 如果 4.4<4 则输出1,否则输出0
二:浮点数的运算
方法一:bc
$ var=3.14
var=`echo"$var*3"| bc`
echo $var
9.42
方法二:awk
var=`echo "3.14 3.14"` | awk '{printf("%g",$1*$2 )}'

五:系统函数 read

在 shell 中 read 用来读取控制台输入
参数:
-t :指定控制台字符输入的时间
-p:指定读取值时界面提示语

$ read -t 7 -p "please input your name" NAME

在7秒内输入你的名字,并将值赋给NAME变量

六:系统函数 basename、dirname

1)basename基本语法:

basename [pathname][suffix]

pathname : 路径加文件名

suffix 为指定的后缀

在不指定后缀的情况下,此命令会删除路径,拿到文件名

如果 suffix 被指定了,basename会将文件名中的 suffix 去掉

basename 路径

$ basename /home/nfs/share/tools/a.txt  

a.txt

$ basename /home/nfs/share/tools/a.txt .txt

a

$ basename ../../a.txt 

a.txt

$ basename /1/2/3/a.txt/ 

a.txt

2)dirname基本语法

dirname 文件绝对路径

从给定的包含文件名的绝对路径中去除文件名,然后返回剩下的路径

$ dirname /home/gcx/test.txt 

/home/gcx

$ dirname  /1/2/3/4/    

/1/2/3

$ dirname   ./../1/2    

./../1

 

七:xargs

先来说明一下这个命令是用来干什么的:
之所以能用到这个命令,关键是由于很多命令不支持“ | ”管道来传递参数,而日常工作中有这个必要,所以就有了 xargs 命令。

命令结构:

    xargs [选项]  命令  命令的原始参数  
    xargs 默认的命令是 echo

常用参数:

-a file:从文件中读入作为 stdin
-d  :对于输入的数据 xargs 使用 -d 来指定参数间的分隔符,默认为空格
-n num : 表示命令在执行的时候一次用的 argument 的个数,默认是用所有的
-t :表示先打印命令,然后再执行。
-r :当没有参数时不运行命令
-i  :用“{}”指代 xargs 预处理后的每行参数。
-I(大写的 i):可以自行指定 占位符
 

对输入数据的处理

xargs 会对输入的数据进行预处理
1)将读取的参数(数据),默认以空格分隔开,可以使用 -d 指定分隔符号
2)默认将输入的参数合并成一行,可以通过 -n num  指定多少个参数一行

$ cat args.txt

a b c d e

f g h 

i j k

$ cat args.txt | xargs 

a b c d e f g h i j k  # 默认合并成一行,默认命令是 echo

$ cat args.txt | xargs -n 5   # 每行设置5个参数

a b c d e 

f g h i j 

k

$ echo "axbxcxd" | xargs -d x   # 修改参数分隔符为 x

a b c d

如何将参数添加到命令上

对预处理得到的每一行参数,都将执行一次命令
通常命令是直接拼接在后面,也可以通过 -i 将参数插入在某个特定位置
-i 默认占位符为 {}
-I replace,--replace=REPLACE 必须指定占位符

$ echo a b c| xargs echo ia ib

ia ib a b c

$ echo a b c | xargs -i echo {} ia ib

a b c ia ib

$ echo a b c|xargs -I {{}} echo {{}} ia ib

a b c ia ib

其它选项

-r 当没有参数时不运行命令
$ echo ""|xargs -r echo ia ib
此时不会运行后面的 echo

八:cut

1、cut基本语法:

cut[选项参数] filename  # 从文件的 每一行剪切字节、字符并输出,源文件内容并不会改变
选项参数:
-f   # 列号,提取第几列
-d  # 分隔符,按照指定分隔符分割列,默认的分隔符是制表符(\t)
例:
cut -d “ ” -f 1 test.txt   # 对test.txt的每一行用空格进行切割,并取出第一列。
cut -d “ ” -f 1,2 test.txt   # 对test.txt的每一行用空格进行切割,并取出第一列与第二列。
cat test.txt | grep “gcx” | cut -d “ ” -f 1
#找出test.txt文件中以gcx开头的行,并对此行用空格进行切割,取出第一列
echo $PATH | cut -d : -f 3- 
# 对系统变量PATH按照冒号进行分割,并取出第三列之后所有的数据
 

九:sort

 
sort用来对文件内容进行排序,并将排序结果标准输出
基本语法:sort(选项)(参数)
常用的选项:
-n   #按照数值大小来排序(ASCII码)
-r   #以相反的顺序排序,常与n连用
-t   #设置排序时所用的分隔字符
-k   #指定需要排序的列
例:按照冒号分割后的第三列倒序排序
sort -t : -nrk 3 a.txt
 
 
 
例:
docker images | grep "$IMAGE_NAME" | grep -w "$IMAGE_TAG" | awk '{print $1}' | xargs -r docker rm -f
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值