Shell简介

Linux环境下通过Shell与内核进行交流,实现使用计算机资源的目的。Linux支持多样的Shell,包括 /bin/sh /bin/bash /bin/tcsh /bin/csh 等,CentOS默认为Bash。

image.png
图1 查看当前系统支持的Shell类型

Bash功能介绍


命令历史

查看记录历史命令文件(家目录下 .bash_history文件)

[root@izuf65cruaexrn54fofumez ~]# ls -a
. .. .bash_history .bash_logout .bash_profile .bashrc .ssh .viminfo
[root@izuf65cruaexrn54fofumez ~]# more .bash_history
Could not chdir to home directory /root: No such file or directory
ls
cd home
ls
cd /hoot
mkdir /root
chown root:root /root
chmod 0700 /root
init 6


命令查看历史命令(history)

[root@izuf65cruaexrn54fofumez ~]# history | more
1 Could not chdir to home directory /root: No such file or directory
2 ls
3 cd home
4 ls
5 cd /hoot
6 mkdir /root
7 chown root:root /root
8 chmod 0700 /root
9 init 6
10 ls


配置最大存储历史命令条数(/etc/profile)

[root@izuf65cruaexrn54fofumez ~]# cat /etc/profile
# /etc/profile
… …
HOSTNAME=/usr/bin/hostname 2>/dev/null
HISTSIZE=1000
if [ “$HISTCONTROL” = “ignorespace” ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
… …


!string & !number 分别执行相匹配历史命令

[root@izuf65cruaexrn54fofumez ~]# !ls
ls
a
[root@izuf65cruaexrn54fofumez ~]# !552
touch a.txt
[root@izuf65cruaexrn54fofumez ~]# ls
a a.txt
[root@izuf65cruaexrn54fofumez ~]#


Ctrl + R 搜索历史操作命令(按下回车执行 ; 按下ESC退出查询)

(reverse-i-search)`vim’: vim /etc/resolv.conf


命令别名

查看当前系统所有别名

[root@izuf65cruaexrn54fofumez ~]# alias
alias egrep=’egrep —color=auto’
alias fgrep=’fgrep —color=auto’
alias grep=’grep —color=auto’
alias l.=’ls -d . —color=auto’
alias ll=’ls -l —color=auto’
alias ls=’ls —color=auto’
alias which=’alias | /usr/bin/which —tty-only —read-alias —show-dot —show-tilde’
[root@izuf65cruaexrn54fofumez ~]# l.
. .. .bash_history .bash_logout .bash_profile .bashrc .ssh .viminfo
[root@izuf65cruaexrn54fofumez ~]#* ll

total 0
-rw-r—r— 1 root root 0 Jul 29 10:02 a
-rw-r—r— 1 root root 0 Jul 29 10:04 a.txt
[root@izuf65cruaexrn54fofumez ~]#


定义新的别名 & 取消别名定义

[root@izuf65cruaexrn54fofumez ~]# alias p=’ping hschen.top’
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# alias
alias egrep=’egrep —color=auto’
alias fgrep=’fgrep —color=auto’
alias grep=’grep —color=auto’
alias l.=’ls -d . —color=auto’
alias ll=’ls -l —color=auto’
alias ls=’ls —color=auto’
alias p=’ping hschen.top’
alias which=’alias | /usr/bin/which —tty-only —read-alias —show-dot —show-tilde’
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# p
PING hancao.github.io (185.199.108.153) 56(84) bytes of data.
64 bytes from 185.199.108.153 (185.199.108.153): icmp_seq=1 ttl=49 time=83.0 ms
64 bytes from 185.199.108.153 (185.199.108.153): icmp_seq=2 ttl=49 time=83.1 ms
64 bytes from 185.199.108.153 (185.199.108.153): icmp_seq=5 ttl=49 time=83.1 ms
^C
—- hancao.github.io ping statistics —-
5 packets transmitted, 5 received, 0% packet loss, time 5147ms
rtt min/avg/max/mdev = 82.523/83.057/83.411/0.468 ms
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# unalias p
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# alias
alias egrep=’egrep —color=auto’
alias fgrep=’fgrep —color=auto’
alias grep=’grep —color=auto’
alias l.=’ls -d .
—color=auto’
alias ll=’ls -l —color=auto’
alias ls=’ls —color=auto’
alias which=’alias | /usr/bin/which —tty-only —read-alias —show-dot —show-tilde’
[root@izuf65cruaexrn54fofumez ~]#


管道与重定向

管道的使用

[root@izuf65cruaexrn54fofumez ~]# echo “hschenpassword” | passwd —stdin hschen
Changing password for user hschen.
passwd: all authentication tokens updated successfully.
[root@izuf65cruaexrn54fofumez ~]#

错误重定向

[root@izuf65cruaexrn54fofumez ~]# ls
a a.txt
[root@izuf65cruaexrn54fofumez ~]# ls -l a b
ls: cannot access b: No such file or directory
-rw-r—r— 1 root root 0 Jul 29 10:02 a
[root@izuf65cruaexrn54fofumez ~]#

只将错误输出重定向

[root@izuf65cruaexrn54fofumez ~]# ls -l a b 2> error.txt
-rw-r—r— 1 root root 0 Jul 29 10:02 a
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# ls
a a.txt error.txt
[root@izuf65cruaexrn54fofumez ~]# cat error.txt
ls: cannot access b: No such file or directory
[root@izuf65cruaexrn54fofumez ~]#

标准输出和错误输出均重定向

[root@izuf65cruaexrn54fofumez ~]# ls -l a b > all.txt 2>&1
[root@izuf65cruaexrn54fofumez ~]# ls
a all.txt a.txt error.txt
[root@izuf65cruaexrn54fofumez ~]# cat all.txt
ls: cannot access b: No such file or directory
-rw-r—r— 1 root root 0 Jul 29 10:02 a
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# ls -l a b &> all.txt
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# cat all.txt
ls: cannot access b: No such file or directory
-rw-r—r— 1 root root 0 Jul 29 10:02 a
[root@izuf65cruaexrn54fofumez ~]#


快捷键

适用于shell命令窗口 和 vim编辑窗口

快捷键 功能
Ctrl + a 光标移动到行首
Ctrl + e 光标移动到行末
Ctrl + f 光标右移一个字符
Ctrl + b 光标左移一个字符
Ctrl + l 清屏
Ctrl + u 删除光标至行首的字符
Ctrl + k 删除光标至行尾的字符
Ctrl + e 终止进程
Ctrl + z 挂起进程(将进程挂在后台处于 Stoped 状态)
Ctrl + w 删除光标前一个单词
Alt + d 删除光标后一个单词
Ctrl + d 删除光标后一个字符

更多操作


Bash使用技巧

重定向技巧

屏蔽无意义信息输出

[root@izuf65cruaexrn54fofumez ~]# echo “password” | passwd —stdin hschen **>**/dev/null
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# echo “password” | passwd —stdin hschen
Changing password for user hschen.
passwd: all authentication tokens updated successfully.
[root@izuf65cruaexrn54fofumez ~]#

标准输出 & 错误输出分离重定向

[root@izuf65cruaexrn54fofumez ~]# id hschen >> user 2>> error
[root@izuf65cruaexrn54fofumez ~]# ls
a all.txt a.txt error error.txt hschen.txt user
[root@izuf65cruaexrn54fofumez ~]# cat user
uid=1003(hschen) gid=1004(hschen) groups=1004(hschen)
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# id tom >> user 2>> error
[root@izuf65cruaexrn54fofumez ~]# cat error
id: tom: no such user
[root@izuf65cruaexrn54fofumez ~]#

命令序列技巧

控制字符 控制命令执行方式 示例
; 多个命令组合,仅按顺序执行
&& 多个命令组合,仅当前命令执行成功,下一个命令才会执行 ls test.txt && cat test.txt
|| ~,仅当前一个命令执行失败,~ gedit || vim hschen.txt
& 后台执行程序(处于运行状态)

[root@izuf65cruaexrn54fofumez ~]# id tom &>/dev/null && echo “Hi, Tom” || echo “No Such User”
No Such User
[root@izuf65cruaexrn54fofumez ~]# id hschen &>/dev/null && echo “Hschen” || echo “No Such User”
Hschen
[root@izuf65cruaexrn54fofumez ~]#

作业控制技巧

&
Ctrl + z
jobs
fg 1
bg 1
Ctrl + c

花括号

生成命令行 & 脚本所需字符串 || 括号中包括 连续序列 & 使用逗号分隔的多个项目

连续序列 echo {0..10} 0 1 2 3 4 5 6 7 8 9 10
echo {0..10..2} 0 2 4 6 8 10
echo a{10..-1} a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 a-1
逗号分隔多个项目 echo {a,b,c} a b c
echo user{1, 5, 8} user1 user5 user8

[root@izuf65cruaexrn54fofumez ~]# mkdir {hschen,wangt}
[root@izuf65cruaexrn54fofumez ~]# ls
hschen wangt
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# ls -ld {hschen,wangt}
drwxr-xr-x 2 root root 4096 Jul 29 14:56 hschen
drwxr-xr-x 2 root root 4096 Jul 29 14:56 wangt
[root@izuf65cruaexrn54fofumez ~]#
[root@izuf65cruaexrn54fofumez ~]# chmod 777 {hschen,wangt}
[root@izuf65cruaexrn54fofumez ~]# ls -ld {hschen,wangt}
drwxrwxrwx 2 root root 4096 Jul 29 14:56 hschen
drwxrwxrwx 2 root root 4096 Jul 29 14:56 wangt
[root@izuf65cruaexrn54fofumez ~]#

变量

自定义变量

定义

name=value

  1. [root@izuf65cruaexrn54fofumez ~]# name = "hschen"
  2. -bash: name: command not found
  3. [root@izuf65cruaexrn54fofumez ~]# name="hschen"
  4. [root@izuf65cruaexrn54fofumez ~]# echo $name
  5. hschen
  6. [root@izuf65cruaexrn54fofumez ~]# name=hschen
  7. [root@izuf65cruaexrn54fofumez ~]# echo $name
  8. hschen

使用

$name

属性

只读:typeset -r name
整型:typeset -i name

预定义

declare INT_NUMBER

标准输入读取变量

read number
read -p “xxx:” number

  1. [root@izuf65cruaexrn54fofumez ~]# read -p "please input a number:" number
  2. please input a number:22
  3. [root@izuf65cruaexrn54fofumez ~]# echo $number
  4. 22

查看所有变量

set

删除变量

unset name

使用范围

name=value只能适用于当前Shell,子进程不会继承

  1. [root@izuf65cruaexrn54fofumez ~]# echo $name
  2. hschen
  3. [root@izuf65cruaexrn54fofumez ~]# bash
  4. [root@izuf65cruaexrn54fofumez ~]# echo $name
  5. [root@izuf65cruaexrn54fofumez ~]#

使用export将变量定义为环境变量

  1. [root@izuf65cruaexrn54fofumez ~]# export name
  2. [root@izuf65cruaexrn54fofumez ~]# echo $name
  3. hschen
  4. [root@izuf65cruaexrn54fofumez ~]# bash
  5. [root@izuf65cruaexrn54fofumez ~]# echo $name
  6. hschen
  7. [root@izuf65cruaexrn54fofumez ~]#

直接定义为环境变量并赋值

  1. [root@izuf65cruaexrn54fofumez ~]# export name=wangt
  2. [root@izuf65cruaexrn54fofumez ~]# echo $name
  3. wangt
  4. [root@izuf65cruaexrn54fofumez ~]# bash
  5. [root@izuf65cruaexrn54fofumez ~]# echo $name
  6. wangt
  7. [root@izuf65cruaexrn54fofumez ~]#

环境变量

  1. [root@izuf65cruaexrn54fofumez ~]# echo $PWD
  2. /root
  3. [root@izuf65cruaexrn54fofumez ~]# echo $BASHPID
  4. 15665
  5. [root@izuf65cruaexrn54fofumez ~]# echo $UID
  6. 0
  7. [root@izuf65cruaexrn54fofumez ~]# echo $GROUPS
  8. 0
  9. [root@izuf65cruaexrn54fofumez ~]# echo $HISTSIZE
  10. 1000
  11. [root@izuf65cruaexrn54fofumez ~]# echo $HOME
  12. /root
  13. [root@izuf65cruaexrn54fofumez ~]# echo $HOSTNAME
  14. izuf65cruaexrn54fofumez
  15. [root@izuf65cruaexrn54fofumez ~]# echo $PWD
  16. /root

直接在环境变量后追加新的值,注意不能直接赋值,否则会覆盖掉之前的值

  1. [root@izuf65cruaexrn54fofumez ~]# echo $PATH
  2. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/.local/bin:/root/bin
  3. [root@izuf65cruaexrn54fofumez ~]# PATH=$PATH:/root
  4. [root@izuf65cruaexrn54fofumez ~]# echo $PATH
  5. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/.local/bin:/root/bin:/root
  6. [root@izuf65cruaexrn54fofumez ~]#

位置变量

调用运行脚本时不同位置的参数,参数之间用空格隔开

$0 当前执行脚本的文件名称 当前执行脚本的文件名称 ./locationnum.sh
$n 第n个参数 第一个参数是 a
$# 参数的个数 参数的个数是 7
$* 将所有的参数当作一个整体代表所有参数的内容 全部的参数是 a b c d e f g
$@ 所有参数分别看作个体看待代表所有参数的内容 全部的参数是 a b c d e f g
$$ 当前进程的ID号码 当前进程ID号 6471
$? 程序的退出代码(0表示执行成功) 程序的退出代码 0

变量的展开替换

之前使用 echo $varname (或者 echo ${varname})来输出指定name的变量值,下面展示下变量的其他展开功能,应用与变量是否被正确设置的环境


varname存在且非NULL 否之
echo ${varname:-word} 返回其值 返回word
echo ${varname:=word} ~ varname设置为word
echo ${varname:?message} ~ 显示varname:message
echo ${varname:+word} ~ 返回NULL
  1. [root@centos7 ~]# NAME=""
  2. [root@centos7 ~]# echo $NAME
  3. [root@centos7 ~]# echo ${NAME:-no user}; echo ${NAME}
  4. no user
  5. [root@centos7 ~]# NAME=""
  6. [root@centos7 ~]# echo ${NAME:?this var is not exist}
  7. -bash: NAME: this var is not exist
  8. [root@centos7 ~]#
  9. [root@centos7 ~]# echo ${NAME:+hschen}
  10. [root@centos7 ~]# echo ${NAME}
  11. [root@centos7 ~]#

以下变量展开对变量的值作修改后输出的场景

echo ${varname#key} 从头开始删除关键字 执行最短匹配
echo ${varname##key} 执行最长匹配
echo ${varname%key} 从未开始删除关键字 执行最短匹配
echo ${varname%%key} 执行最长匹配
echo ${varname/old/new} 将old替换为new 仅替换第一个出现的old
echo ${varname//old/new} 替换所有的old

数组

创建数组

  1. [root@centos7 ~]# Array[0]=0
  2. [root@centos7 ~]# echo $Array
  3. 0
  4. [root@centos7 ~]# echo ${Array[0]}
  5. 0
  6. [root@centos7 ~]# Array[1]=1 Array[2]=2
  7. [root@centos7 ~]# echo ${Array[1]} ${Array[2]}
  8. 1 2
  9. [root@centos7 ~]#
  1. [root@centos7 ~]# Apple=(red yellow blue)
  2. [root@centos7 ~]# echo ${Apple[0]} ${Apple[1]} ${Apple[2]}
  3. red yellow blue
  4. [root@centos7 ~]#

预定义空数组变量

  1. [root@centos7 ~]# declare -a bilibili
  2. [root@centos7 ~]# echo ${bilibili}
  3. [root@centos7 ~]#

调用数组变量值

获取数组中所有内容

  1. [root@centos7 ~]# echo ${Apple[@]}
  2. red yellow blue
  3. [root@centos7 ~]# echo ${Apple[*]}
  4. red yellow blue
  5. [root@centos7 ~]#

获取数组长度

  1. [root@centos7 ~]# echo ${#Apple}
  2. 3
  3. [root@centos7 ~]# echo ${#Apple[@]}
  4. 3
  5. [root@centos7 ~]# echo ${#Apple[*]}
  6. 3

获取数组中指定值的长度

  1. [root@centos7 ~]# echo ${#Apple[1]}
  2. 6
  3. [root@centos7 ~]# echo ${#Apple[0]}
  4. 3
  5. [root@centos7 ~]# echo ${#Apple[2]}
  6. 4
  7. [root@centos7 ~]# echo ${#Apple[3]}
  8. 0
  9. [root@centos7 ~]# echo ${Apple[0]}
  10. red
  11. [root@centos7 ~]# echo ${Apple[1]}
  12. yellow
  13. [root@centos7 ~]# echo ${Apple[2]}
  14. blue
  15. [root@centos7 ~]#

算术运算与测试

$((expression))

  1. [root@centos7 ~]# echo $((5**2))
  2. 25
  3. [root@centos7 ~]#

expr

  1. [root@centos7 ~]# expr 10 \* 2
  2. 20
  3. [root@centos7 ~]# expr 10 * 2
  4. expr: syntax error
  5. [root@centos7 ~]#

test

  1. [root@centos7 shell]# test -e file.txt && echo "文件存在" || echo "文件不存在"
  2. 文件存在
  3. [root@centos7 shell]#

[ expression ]

  1. [root@centos7 shell]# [ -z $PATH ] && echo "字符串长度为0" || echo "字符串长度非0"
  2. 字符串长度非0
  3. [root@centos7 shell]# [ -z $FAKE ] && echo "字符串长度为0" || echo "字符串长度非0"
  4. 字符串长度为0
  5. [root@centos7 shell]#
  1. [root@centos7 shell]# echo $PATH
  2. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/.local/bin:/root/bin
  3. [root@centos7 shell]#
  4. [root@centos7 shell]# echo $FAKE
  5. [root@centos7 shell]# [ -n $PATH ] && echo "字符串长度非0" || echo "字符串长度为0"
  6. 字符串长度非0
  7. [root@centos7 shell]# [ -n $FAKE ] && echo "字符串长度非0" || echo "字符串长度为0"
  8. 字符串长度非0
  1. [root@centos7 shell]# [ $PATH ] && echo "字符串长度非0" || echo "字符串长度为0"
  2. 字符串长度非0
  3. [root@centos7 shell]# [ $FAKE ] && echo "字符串长度非0" || echo "字符串长度为0"
  4. 字符串长度为0

Shell引号

反斜线 \ 屏蔽紧随其后的特殊字符,比如* 、>、回车
单引号 ‘ ‘ 屏蔽包括在内的特殊字符
双引号 “ “ 不屏蔽`、\、$,如果要屏蔽在字符前使用\
反引号 或$( ) 命令字符转换为命令的执行结果

SHELL脚本编写示例

grep | sed | awk | 正则表达式

给定文件 file.txt 只打印该文件第十行 (考虑文件少于10行的情况)

  1. 数据行数 >= 10行

    1. [hschen@izuf65cruaexrn54fofumez ~]$ head file.txt | tail -1
    2. Line 10
    3. [hschen@izuf65cruaexrn54fofumez ~]$ cat file.txt
    4. Line 1
    5. Line 2
    6. Line 3
    7. Line 4
    8. Line 5
    9. Line 6
    10. Line 7
    11. Line 8
    12. Line 9
    13. Line 10
    14. Line 11
    15. [hschen@izuf65cruaexrn54fofumez ~]$
  2. 数据行数 <= 10行

  1. [hschen@izuf65cruaexrn54fofumez ~]$ awk '{if(NR==10) print $0}' file.txt
  2. Line 10
  3. [hschen@izuf65cruaexrn54fofumez ~]$ sed -n 10p file.txt
  4. [hschen@izuf65cruaexrn54fofumez ~]$ cat file.txt
  5. Line 1
  6. Line 2
  7. Line 3
  8. Line 4
  9. Line 5
  10. Line 6
  11. Line 7
  12. Line 8
  13. Line 9
  14. [hschen@izuf65cruaexrn54fofumez ~]$
  15. [hschen@izuf65cruaexrn54fofumez ~]$ tail -n+10 file.txt | head -1
  16. [hschen@izuf65cruaexrn54fofumez ~]$

给定一个包含电话号码列表(一行一个号码)的文本文件 file.txt 输出所有有效的电话号码(xxxx-xxx-xxx 或者 (xxx)xxx-xxxx)前后没有多余的空格字符

  1. [root@izuf65cruaexrn54fofumez ~]# grep "^\(([0-9]\{3\}) \|[0-9]\{3\}-\)[0-9]\{3\}-[0-9]\{4\}$" file.txt
  2. 987-123-4567
  3. 987-123-4567
  4. 987-123-4567
  5. 987-123-4567
  6. (123) 456-7890
  1. grep "^\(([0-9]\{3\}) \|[0-9]\{3\}-\)[0-9]\{3\}-[0-9]\{4\}$" file.txt
  2. grep -P "^(\(\d{3}\) |\d{3}-)\d{3}-\d{4}$" file.txt

用 ^ 和 $ 在开头和结尾表示包含字符串前后都没有其他字符 ; [0-9]表示从 0 到 9 的10个数任选其一 ; {3} 表示前面出现的字符有 3 次 ; ( pattern1 | pattern2 ) 表示从 pattern1 和 pattern2中或的关系选择匹配 ;

加上 -P 参数后,( pattern1 | pattern2 )表示 或 的关系 ; 不过()内的括号 要利用 \ 转义 ; [0-9] 可以用 \d 表示

  1. sed -n '/^\([0-9]\{3\}-\|([0-9]\{3\}) \)[0-9]\{3\}-[0-9]\{4\}$/p' file.txt
  2. sed -n -r "/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/p" file.txt

-n 表示 sed静默输出,屏蔽自动打印。默认在所有脚本执行后,将自动打印模式空间中的内容。
/正则表达式/ 使用sed程序必须用两个斜杆来包括正则
p sed中在最后写上 p 才能将匹配到的字符串打印出来

-r 表示扩展正则表达式: {3} 不用加斜杆 ;选择表达式 ( | )\ 也不用加斜杆了 ;但括号()必须使用 \ 转义

  1. awk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt

awk程序也要 利用 /正则表达式/
默认awk程序动作 action 为输出
选择表达式 ( | );括号要记得转义

wc 统计词频

  1. [root@izuf65cruaexrn54fofumez ~]# cat words.txt|xargs | \
  2. awk '{for(i=1;i<=NF;i++){res[$i]+=1}}END{for(k in res){print k" "res[k]}}' \
  3. | sort -k2,2rn -k1
  4. the 4
  5. sunny 2
  6. is 2
  • xargs 将多行文件转换为一行文件;
  • NF 表示以默认空格为分隔符统计的字段数;
  • $i 表示第i个字段数;
  • 思想:利用赋值数字索引的想法,数值 key 用来存储 字段 ,value用来存储 统计的数目
  • sort 表示排序 -k2表示按照第二列排序,2rn表示按照数字逆序排序, -k1表示在第二列相同的情况下,按照第一列排序
  • for循环:注意两段for循环一定要分别利用 {}包括起来
  1. [root@izuf65cruaexrn54fofumez ~]# cat words.txt | xargs -n 1 | sort |
  2. uniq -c | sort -k1,1nr | awk '{print $2, $1}'
  3. c 3
  4. b 2
  5. a 1
  • xargs -n 1 表示将该文件显示为一列,一列为一个词
  • sort 将一列字符按照从a到z的顺序排列,存在相同词排在一起
  • uniq -c 去除重复字符,并且第一列显示词频数,第二列显示对应词
  • sort -k1,1nr 按照第一列字符顺序逆序排序
  • awk ‘{print $2, $1}’显示第二列 第一列
  1. cat words.txt | sed 's/[ ][ ]*/\n/g' | grep -v "^$" | sort | uniq -c | sort -k1,1nr | awk '{print $2, $1}'
  2. [root@izuf65cruaexrn54fofumez ~]# cat words.txt | sed 's/[ ][ ]*/\n/g' | grep -v "^$" | sort | uniq -c | sort -k1,1nr | awk '{print $2, $1}'
  3. c 3
  4. b 2
  5. a 1
  • sed 替换: ‘s/pattern/replacement/flags这里 pattern = [ ][ ]* 表示最多一个空格被匹配(第一个空格为必须;第二个空格可有可多个);replacement 这里是 \n 表示匹配第 n 个子串,即之前的正则表达式;flags这里是 g 表示对模式空间所有匹配进行全局更改
  • grep显示非空白行:grep -v ^$
  • sort -k1,1nr 可以简写为 sort -nr 表示以数字逆序显示

逆转文件

把列变成行,行变成列

  1. [root@centos7 shell]# cat file.txt
  2. name age
  3. alice 21
  4. ryan 30
  1. [root@centos7 shell]# cat secondtransposed.sh
  2. #!/bin/bash
  3. line=$(awk 'END {print NF}' file.txt)
  4. for((i=1;i<=${line};i++))
  5. do
  6. col=$(cut -f $i -d " " file.txt)
  7. echo $col
  8. done
  9. [root@centos7 shell]#
  1. [root@centos7 shell]# ./secondtransposed.sh
  2. name alice ryan
  3. age 21 30
  4. [root@centos7 shell]#