Linux Shell 脚本攻略-详细阅读总结

根据《linux shell 脚本攻略》按自己的思路进行了总结和内容划分调整。
省略和 Web交互 和 MySql 数据库、系统管理监控(当前工作中太过少用),和 部分少用的指令,也补充个了个人工作中常用指令,更多的是面向个人使用。多用man查看 命令帮助。

文章目录

      • 一、概念
          • 1.1 Shell
          • 1.2 Shell脚本
          • 1.3 正则表达式
      • 二、 基础语法
          • 2.1 变量(读/写/查看/环境变量)
          • 2.2 数学计算
          • 2.3 表达式(逻辑运算,条件比较)
          • 2.4 语句(条件语句/循环语句)
          • 2.5 函数与参数
          • 2.6 注释---以#开头该行从#到行尾注释
      • 三、GNU/Linux 基础命令
          • 3.1 输出 echo/printf 与 输入 read
          • 3.2 设置命令别名 alias / 查看命令类型type /历史命令 history
          • 3.3 获取/设置 日期date 与 延时控制sleep 命令执行时间time
          • 3.4 基础字符文本处理 转化tr / 排序sort /消除重复 uniq /分割split/ %、#取字段
          • 3.5 工作控制 查看jobs / 前台终止ctrl+c /后台执行& / 切后台 ctrl+z / 切前台fg/ 后台运行bg / 计划任务 cron
          • 3.6 进程控制 查看ps / 动态top / 发送信号kill
          • 3.7 内存状态 free或cat /proc/meminfo / 磁盘状态 df du / 系统信息 uname
          • 3.8 网络控制 配置ifconfig/联通检查ping/ 服务分析netstat
          • 3.4 【高阶使用】多个命令组合 pipe ‘|’ 与 转化传递 xargs
      • 四、文件相关 命令 及 技巧
          • 4.1 文件 创建touch/删除rm/链接ln/移动mv/改名rename /复制cp
          • 4.2 文件 列表ls/ 属性file / 查找find/ 权限chmod
          • 4.3 文件内容查看 全部cat / 按页more / 前几行head/ 尾几行tail / 二进制od
          • 4.4 文件统计 wc(行/单词/字符)
          • 4.5 文件与重定向<、>和>>
          • 4.6 文件比较 comm 差异diff 与 补丁patch
          • 4.7 文件 归档打包与压缩 tar
          • 4.8 目录相关 创建mkdir/删除 rmdir / 切换cd /打印目录输tree
          • 4.9 【高阶技巧】通过网络传输文件 ftp/ setp/ rsync/ scp
      • 五、文本相关 命令 和 技巧
          • 5.2 文件搜索文本 grep
          • 5.3 文本切分 cut 与 合并 paste
          • 5.4 文本替换与修改 流编辑器sed
          • 5.5【高阶技巧】高级文本处理 数据流处理器awk(暂略 )

一、概念

1.1 Shell

Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(命令解析器),接收用户命令,然后调用相应的应用程序。shell环境使得用户能与操作系统的核心功能进行交互。
图形界面/终端 切换:CTRL+ALT+F1~F6切换,F1即切到tty1/F7切到图形界面/F3切换到命令行(T 在图形界打开终端)

1.2 Shell脚本

一系列需要执行的命令写入其中的文件,然后通过shell来执行。
脚本内容:shell脚本通常是以类似 #!/bin/bash 开始的文本文件。(中#!位于解释器路径之前,表面解释器位置)每个命令或是命令序列是通过使用分号或换行符来分隔的;
运行脚本的方式:(1)bash script.sh(使用bash直接运行文件)(2)./script.sh (直接执行文件,需要有可执行权限)
bashrc文件:启动shell时,它一开始会执行一组命令来定义诸如提示文本、颜色等各类设置,如位于~/.bashrc */

1.3 正则表达式

正则表达式是由字面文本和具有特殊意义的符号组成的。我们可以根据具体需求,使用它们
构造出适合的正则表达式来匹配文本。因为正则表达式是一种匹配文本的通用语言。在shell中 大量命令都支持 通过正则表达式 去做 匹配,如 find查找文件,grep搜索文本 等。
正则表达式此处不做展开。
Linux Shell 脚本攻略-详细阅读总结_第1张图片

二、 基础语法

2.1 变量(读/写/查看/环境变量)

Bash中每一个变量的值都会以字符串的形式存储,不需要在使用之前声明其类型,直接赋值就行。
写变量:变量使用var=value进行赋值(=前后不能有空格,如果value种带空格必须用引号保护),或者使用var+=add_value进行变量追加赋值
读变量:变量名前加$可以打印其内容;使用set命令 查看当前全部变量;使用 env 查看全部环境变量。
环境变量:未在当前进程中定义,而从父进程中继承而来的变量,export命令用来设置环境变量。从当前shell脚本执行的任何应用程序都会继承这个变量,如环境变量PATH为可执行文件查找路径

goodboy@ubuntu:~$ var=1234 #注意不能添加空格
goodboy@ubuntu:~$ echo $var
1234
goodboy@ubuntu:~$ var+=5678
goodboy@ubuntu:~$ echo $var
12345678
goodboy@ubuntu:~$ echo "we have get var $var"
we have get var 12345678
goodboy@ubuntu:~$ echo "we have get var ${var}"
we have get var 12345678
goodboy@ubuntu:~$ echo "$var length is ${#var}"
12345678 length is 8
2.2 数学计算

在Bash shell环境中,可以利用let、(( ))和[]执行基本的算术操作。 更高级的运算可以用bc(于数学运算的高级工具,可以借助它执行浮点数运或者 进制转化、求平方根等)
let 可以直接执行基本的算术操作(包自减)。当使用let时,变量名之前不需要再添加 $ 。操作符[]的使用方法和let命令类似,也可以使用(()),但使用(())时,变量名之前需要加上 $ 。

goodboy@ubuntu:~$ num1=4
goodboy@ubuntu:~$ num2=5
goodboy@ubuntu:~$ let sum=num1+num2
goodboy@ubuntu:~$ echo $sum
9
goodboy@ubuntu:~$ let num1--
goodboy@ubuntu:~$ echo $num1
3
goodboy@ubuntu:~$ let num1+=5
goodboy@ubuntu:~$ echo $num1
8
goodboy@ubuntu:~$ sum2=$[num1+num2]
goodboy@ubuntu:~$ sum3=$((num1+num2))
2.3 表达式(逻辑运算,条件比较)

(1)算数比较:条件通常被放置在封闭的中括号内。一定要注意在[或]与操作数之间有一个空格。
[ $var -eq 0 ] 表示 当 $var 等于 0 时为真。算术条件判断 如下,

-eq等于/-gt大于/ -lt小于 / -ge大于或等于 / -le小于或等于 /
# 可以按照下面的方法结合多个条件进行测试:
[ $var1 -ne 0 -a $var2 -gt 2 ] #使用逻辑与-a 
[ $var1 -ne 0 -o $var2 -gt 2 ] #逻辑或

(2)文件系统相关测试:我们可以使用不同的条件标志测试不同的文件系统相关的属性

[ -f $file_var ]:如果给定的变量包含正常的文件路径或文件名,则返回真。
[ -x $var ]:如果给定的变量包含的文件可执行,则返回真。
[ -d $var ]:如果给定的变量包含的是目录,则返回真。
[ -e $var ]:如果给定的变量包含的文件存在,则返回真。
[ -c $var ]:如果给定的变量包含的是一个字符设备文件的路径,则返回真。
[ -b $var ]:如果给定的变量包含的是一个块设备文件的路径,则返回真。
[ -w $var ]:如果给定的变量包含的文件可写,则返回真。
[ -r $var ]:如果给定的变量包含的文件可读,则返回真。
[ -L $var ]:如果给定的变量包含的是一个符号链接,则返回真。

(3)字符串比较:使用字符串比较时,最好用双中括号,时候采用单个中括号会产生错误。

[[ $str1 = $str2 ]]:当str1等于str2,文本是一模一样,返回真。
[[ $str1 == $str2 ]]:这是检查字符串是否相等的另一种写法。
[[ $str1 != $str2 ]]:如果str1和str2不相同,则返回真。
[[ $str1 > $str2 ]]:如果str1的字母序比str2大,则返回真。
[[ $str1 < $str2 ]]:如果str1的字母序比str2小,则返回真。
[[ -z $str1 ]]:如果str1包含的是空字符串,则返回真。
[[ -n $str1 ]]:如果str1包含的是非空字符串,则返回真。

(4)逻辑运算:使用逻辑运算符 && 和 || 能够很容易地将多个条件组合起来

if [[ -n $str1 ]] && [[ -z $str2 ]] ; 
then 
 commands; 
fi
2.4 语句(条件语句/循环语句)

条件语句:我们可以用if、if else以及逻辑运算符进行测试,用比较运算符来比较数据项。除此之外,还有一个test命令也可以用于测试。这些命令的用法如下

if condition; 
then 
 commands; 
else if condition; then 
 commands; 
else 
 commands; 
fi

循环语句:while循环命令和if类似

while condition;
do
	command;
done;
2.5 函数与参数

定义与调用:定义如下,直接使用函数名可以调用函数,函数名 arg1 arg2 …可以携带参数调用。调用完函数后 $? 会保存返回值(0为成功);

myfunc() {
    echo "hello word!";
} 
mytest() { 
 echo $1, $2; #访问参数1和参数2 
 echo "$@";#以列表的方式一次性打印所有参数
 echo "$*"; #类似于$@,但是参数被作为单个实体
 echo "$#"; #参数个数
 return 0; #返回值
}
myfunc; # 函数调用
mytest arg_a arg_b; #函数带参数调用
#//输出如下//
goodboy@ubuntu:~$ ./test.sh 
hello word!
arg_a, arg_b
arg_a arg_b
arg_a arg_b
2
2.6 注释—以#开头该行从#到行尾注释

三、GNU/Linux 基础命令

命令执行返回值:当一个命令发生错误并退回时,它会返回一个非0的退出状态;成功返回0。退出状态可以从特殊变量$?中获得(在命令执行之后立刻运行echo $?,就可以打印出退出状态)。

3.1 输出 echo/printf 与 输入 read

echo “XXX”(每次调用后会添加一个换行符 使用选项-n来忽略结尾
的换行符,如果不带双引号也可打印,但是遇到;会认为命名结束)

goodboy@ubuntu:~$ echo -e "\e[1;31m This is red text \e[0m"
 This is red text 
 /* \e[1;31将颜色设为红色,\e[0m将颜色重新置回。只需要将31替换成想要的颜色码就可以了。*/

printf 能使用格式化字符串,

goodboy@ubuntu:~$ printf "%-5s %-10s %-4s\n" No Name Mark
No    Name       Mark

read:它用于从键盘或标准输入中读取文本。

3.2 设置命令别名 alias / 查看命令类型type /历史命令 history

alias:别名就是一种便捷方式,以省去用户输入一长串命令序列的麻烦。alias new_command=‘command sequence’

alias ls='ls --color=auto' #如~/.bashrc中常见这句,就是把ls替换位带颜色参数的ls命令,省去使用时追加color

type :可以查看输入命令类型,如下,常见三种类型:别名alias,可执行文件,shell内置命令;

goodboy@ubuntu:~$ type ls
ls is aliased to `ls --color'
goodboy@ubuntu:~$ type find
find is /usr/bin/find
goodboy@ubuntu:~$ type help
help is a shell builtin

history :输入后 打印出最近输入的命令 历史纪录。

3.3 获取/设置 日期date 与 延时控制sleep 命令执行时间time

在类Unix系统中,日期被存储成一个整数,其大小为自世界标准时间(UTC)①1970年1月1日0时0分0秒②起所流逝的秒数。这种计时方式称为纪元时或Unix时间
date :可以按各种格式输出, 格式字符串结合+作为date命令参数,–date可以作为输入,脚本中可以用类似start_time=$(date +%s) 读取时间, 例如:

goodboy@ubuntu:~$ date
Sun Jun  7 03:35:28 PDT 2020
goodboy@ubuntu:~$ date +%s #unix时间
1591526136
goodboy@ubuntu:~$ date "+%d %B %Y"
07 June 2020
goodboy@ubuntu:~$ start_time=$(date +%s)
goodboy@ubuntu:~$ echo $start_time 

Linux Shell 脚本攻略-详细阅读总结_第2张图片
sleep:延时控制 默认单位位秒s(还有m分钟 h小时 d天),sleep 0.1效果 和 sleep 0.1s 一样 为0.1秒。
time COMMAND:执行cmd时候 测试时间。

3.4 基础字符文本处理 转化tr / 排序sort /消除重复 uniq /分割split/ %、#取字段

tr :对来自标准输入stdin的内容进行字符替换、字符删除以及重复字符压缩的**转换(translate)**命令。tr [options] set1 set2 将来自stdin的输入字符从set1映射到set2,然后将输出写入stdout。(常用参数:-d删除)

goodboy@ubuntu:~$ echo "HELLO WHO IS THIS" | tr 'A-Z' 'a-z' #大写转小写
hello who is this
goodboy@ubuntu:~$ echo "Hello 123 world 456" | tr -d '0-9' #删除数字字符
Hello  world 

sort与uniq :既可以从特定的文件,也可以从stdin中获取输入,包含大量的选项,能够对文件数据进行各种排序。uniq是一个经常与sort一同使用的命令(只能作用于排过序的数据输入)。它的作用是从文本或stdin中提取唯一(或重复)的行。

sort unsorted.txt | uniq

split : split文件分割成多个更小的片段。常用参数 -b按大小分割,-l按行号分割。

goodboy@ubuntu:~$ split -l 1 tmp.txt  # 按1行splt tmp.txt文件
goodboy@ubuntu:~$ ls
tmp.txt  xaa  xab  xac

% # 提取 文件字段:借助%操作符可以轻松将名称部分从“名称.扩展名”这种格式中提取出来,${VAR%.*}。%属于非贪婪(non-greedy)操作。 %%与%相似,行为模式却是贪婪的。# 操作符从文件名中提取扩展名,求值方向是从左向右,##类似。

goodboy@ubuntu:~$ file="tmp.txt"
goodboy@ubuntu:~$ echo ${file%.*}
tmp
goodboy@ubuntu:~$ file2="tmp.a.b.c"
goodboy@ubuntu:~$ echo ${file2%.*} ${file2%%.*}
tmp.a.b tmp
goodboy@ubuntu:~$ echo ${file2#*.} ${file2##*.}
a.b.c c
3.5 工作控制 查看jobs / 前台终止ctrl+c /后台执行& / 切后台 ctrl+z / 切前台fg/ 后台运行bg / 计划任务 cron

jobs相关命令 是 shell自带命令。用于显示Linux中的任务列表及任务状态,包括后台运行的任务。任务号是以普通用户的角度进行的,而进程号则是从系统管理员的角度来看的。一个任务可以对应于一个或者多个进程号。类似window的任务管理器。
工作查看 jobs(选项)(参数):附加参数: -l显示进程号 -p仅任务对应的显示进程号;-n显示任务状态的变化;-r仅输出运行状态的任务;-s:仅输出停止状态的任务。正在前台执行的命令,使用ctrl+c直接终止,ctrl+z 会 切换到后台。
后台工作切换 fg与bg:使用fg % [任务编号] 可以把后台切换到前台。bg % [任务]可以直接在后台运行。
后台执行& :如果执行命令结尾追加&,任务会直接在后台运行。

goodboy@ubuntu:~/tmp$ vi ./tmp.txt #在VI的编辑界面 ctrl+z,将执行认为 切换到后台(stop)
[1]+  Stopped                 vi ./tmp.txt
goodboy@ubuntu:~/tmp$ vi ./tmp2.txt #再VI的编辑一个文件,继续 ctrl+z,将执行认为 切换到后台(stop)
[2]+  Stopped                 vi ./tmp2.txt
goodboy@ubuntu:~/tmp$ jobs
[1]-  Stopped                 vi ./tmp.txt
[2]+  Stopped                 vi ./tmp2.txt
goodboy@ubuntu:~/tmp$ fg %1 #把编号1的工作切换到前台,继续 vi ./tmp.txt
###输出略
goodboy@ubuntu:~/tmp$ bg %2 #把编号2的工作 直接在后台执行
[2]- vi ./tmp2.txt &

计划任务cron :是任务在约定的时间执行已经计划好的工作。cron服务器可以根据配置文件约定的时间来执行特定的任务。cron启动后,它会读取它的所有配置文件(全局性配置文件/etc/crontab,以及每个用户的计划任务配置文件),然后cron会根据命令和执行时间来按时来调用度工作任务。cron服务提供crontab命令来设定cron服务的。
输入crontab -e执行,里面有详细介绍:

# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
3.6 进程控制 查看ps / 动态top / 发送信号kill

进程信息收集ps:用于收集系统中进程的详细信息。这些信息包括CPU使用情况、正在执行的命令、内存占用、进程状态等。如果不使用任何参数,ps将显示运行在当前终端(TTY)
中的进程;常用可选参数:-A/e所有的不同process均显示出来 -l 较详细的输出该该PID的信息 -f更为完整的输出

goodboy@ubuntu:~$ ps
   PID TTY          TIME CMD
 38713 pts/1    00:00:00 bash
 38775 pts/1    00:00:00 vi
 38777 pts/1    00:00:00 ps
goodboy@ubuntu:~$ ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 Jun08 ?        00:00:01 /sbin/init
root          2      0  0 Jun08 ?        00:00:00 [kthreadd]
root          3      2  0 Jun08 ?        00:00:00 [ksoftirqd/0]
root          5      2  0 Jun08 ?        00:00:00 [kworker/0:0H]

进程动态查看top :默认会输出一个占用CPU最多的进程列表。输出结果每隔几秒就会更新。Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况。 常用附加命令:-d [秒数] 每间隔几秒刷新一次

top - 08:12:32 up 1 day, 20:23,  3 users,  load average: 0.00, 0.00, 0.00  #时间/运行时间/用户数/系统负载 1/5/15分钟 平均值
Tasks: 247 total,   1 running, 244 sleeping,   1 stopped,   1 zombie #进程数状态,总/运行/休眠/停止/僵尸
%Cpu(s):  2.4 us,  1.4 sy,  0.0 ni, 96.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st #cpu占用比 用户态/内核/用户变优先级/空闲/等待输入/硬中断/软中断/虚拟机
KiB Mem:   2029920 total,  1773960 used,   255960 free,   118092 buffers
KiB Swap:  2094076 total,      208 used,  2093868 free.   954876 cached Mem
   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND      
  1117 root      20   0  376676  81904  42088 S  2.6  4.0   9:56.73 Xorg         
 38878 goodboy   20   0   29160   3136   2568 R  0.3  0.2   0:00.03 top          
     1 root      20   0   37360   7948   2772 S  0.0  0.4   0:01.54 init       

发送信kill:kill 参数 进程号。信号是Linux中的一种进程间通信机制,当进程接收到一个信号时,它会通过执行对应的信号处理程序(signal handler)来进行响应。kill -l 列出所有信号名称

goodboy@ubuntu:~$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
#省略部分...
goodboy@ubuntu:~$ jobs
[1]+  Stopped                 vi tmp.txt
goodboy@ubuntu:~$ kill -9 %1 #向工作1发送终止信号
goodboy@ubuntu:~$ ps 
   PID TTY          TIME CMD
 38713 pts/1    00:00:00 bash
 39151 pts/1    00:00:00 vi
 39153 pts/1    00:00:00 ps
goodboy@ubuntu:~$ kill -9 39151 # 向进程号39151的进程发送终止信号
3.7 内存状态 free或cat /proc/meminfo / 磁盘状态 df du / 系统信息 uname

cat /proc/meminfo和free命令:可以查看系统内存状态,cat /proc/39316/statm 查看39316进程内存使用情况。

goodboy@ubuntu:~$ free
             total       used       free     shared    buffers     cached
Mem:       2029920    1767016     262904      19012     118420     954880
-/+ buffers/cache:     693716    1336204
Swap:      2094076        208    2093868
goodboy@ubuntu:~$ cat /proc/meminfo #以下只列举了部分
MemTotal:        2029920 kB #所有可用RAM大小(即物理内存减去一些预留位和内核的二进制代码大小)
MemFree:          265316 kB #LowFree与HighFree的总和,被系统留着未使用的内存
MemAvailable:    1286340 kB #用的内存,有些内存已被使用但可回收,可回收的内存加MemFree
Buffers:          118396 kB #用来给文件做缓冲大小
VmallocTotal:   34359738367 kB #可以vmalloc虚拟内存大小
VmallocUsed:           0 kB
VmallocChunk:          0 kB

df和du:Linux中用于统计磁盘使用情况的两个重要命令。df是disk free的缩写,du是disk usage的缩写。du附加命令:-a递归地输出指定目录及所有文件的统计结果 -h自动选择合适的单位方便阅读

goodboy@ubuntu:~$ du tmp.txt  #找出某个文件(或多个文件)占用的磁盘空间(默认字节)
12	tmp.txt
goodboy@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            978M  4.0K  978M   1% /dev
tmpfs           199M  1.1M  198M   1% /run
/dev/sda1        18G  4.6G   13G  28% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
none            5.0M     0  5.0M   0% /run/lock
none            992M  488K  991M   1% /run/shm
none            100M   48K  100M   1% /run/user

采集系统信息uname:各种系统信息, -n主机名 -a 打印内核版本 -r 内核发行版本 -m主机类型。

3.8 网络控制 配置ifconfig/联通检查ping/ 服务分析netstat

ifconfig :用于配置及显示网络接口、子网掩码等详细信息。它通常位于/sbin/ifconfig中。不带参数 会直接列出当前网络接口配置。

 ifconfig wlan0 192.168.0.80 netmask 255.255.252.0 #设置ip地址和子网掩码
 fconfig eth0 hw ether 00:1c:bf:87:25:d5 #配置硬件mac地址

ping:验证网络上两台主机连通性的诊断工具。ping ADDRESS ,ADDRESS可以是主机名、域名或者IP地址。ping会连续发送分组,回应信息将被打印在终端上。用Ctrl+C来停止ping命令

3.4 【高阶使用】多个命令组合 pipe ‘|’ 与 转化传递 xargs

pipe符号 ‘|’ :输入通常是通过stdin或参数传递给命令。输出要么出现在stderr,要么出现在stdout。 cmd1 | cmd2 | cmd3 这些命令被称为过滤器(filter)。我们使用管道(pipe)连接每个过滤器。cmd1的输出传递给cmd2,而cmd2的输出传递给cmd3。

goodboy@ubuntu:~$ cat tmp.txt | grep hello  #把tmp.txt文件内容通过cat输出 传给 grep搜索包含hello行
     printf("hello word\n");

xarges:些命令只能以命令行参数的形式接受数据,而无法通过stdin接受数据流,这个时候|无法排上用场,xargs能够处理stdin并将其转换为特定命令的命令行参数。(类似于find命令中的 -exec),常用参数 -n X 每次执行需要X个参数-I {} 指定了替换字符串(命令以循环的方式执行。如果有3个参数就执行3次,每次执行中{}都会被替换为相应的参数)

goodboy@ubuntu:~$ find . -name "*.c" | wc -l # wc实际统计的是find指令输出内容
2
goodboy@ubuntu:~$ find . -name "*.c" | xargs wc -l #wc统计的针对是find到的文件
 0 ./b.c
 6 ./a.c
 6 total
 goodboy@ubuntu:~$ cat tmp.txt #tmp文件中有两行,内容如果直接wc结果为内容对应2行
./b.c
./a.c
goodboy@ubuntu:~$ cat tmp.txt | xargs wc -l #使用xargs后,把文本内容调整为入参 全部传入wc统计
 0 ./b.c
 6 ./a.c
 6 total
goodboy@ubuntu:~$ cat tmp.txt | xargs -I {} wc -l {} #使用-I命令,wc每次都统计一个文件(没有出现totoal)
0 ./b.c
6 ./a.c

四、文件相关 命令 及 技巧

文件描述符 :与某个打开的文件或数据流相关联的整数,0、1以及2是系统预留的。
0:stdin(标准输入)1:stdout(标准输出)2 : stderr(标准错误)

4.1 文件 创建touch/删除rm/链接ln/移动mv/改名rename /复制cp

touch :修改文件时间戳,如果没有会创建一个空文件,如果文件已经存在,那么touch命令会将与该文件相关的所有时间戳都更改为当前时间。

# 批量生成100个空文件
for name in {1..100}.txt 
do 
 touch $name 
done

ln:硬链接(通过索引节点来进行的连接,硬连接为0文件被真正删除)与软链接(又叫符号链接,类似于Windows中的快捷方式。删除符号链接不会影响到原始文件)。

ln source_file hard_link #硬链接
ln -s source_file soft_link #软链接
readlink link #读链接

rename/mv :rename利用Perl正则表达式修改文件名;mv可以移动文件,移动的过程也可以指定新的名称 进行重命名。

 rename *.JPG *.jpg  #将*.JPG更名为 *.jpg
 rename 's/ /_/g' * #将文件名中的空格替换成字符“_”
 find path -type f -name "*.mp3" -exec mv {} target_dir \; # 将所有的 .mp3文件移入给定的目录
 # {} 会被替换为 多次单次执行,每次执行输入为find找到的文件。
#!/bin/bash 
#用途: 重命名 .jpg 和 .png 文件 
#该脚本将当前目录下所有的.jpg和.png文件重命名,
#新文件名的格式为image-1.jpg、image-2.jpg、image-3.jpg、image-4.png等
count=1; 
for img in `find . -iname '*.png' -o -iname '*.jpg' -type f -maxdepth 1` 
do 
	new=image-$count.${img##*.} 
	echo "Renaming $img to $new" 
	mv "$img" "$new" 
	let count++ 
done
4.2 文件 列表ls/ 属性file / 查找find/ 权限chmod

ls :显示文件列表,重要参数 -l 列出文件的详细信息(起始标记文件类型:- 普通文件。d 目录。c 字符设备。b 块设备。l 符号链接。s 套接字。p 管道。剩下的部分可以划分成三组,每组3个字符(— --- —)。对应用户权限,用户组权限,用户权限。读权限r,写权限w,执行权限x,-表明没有对应权限), -a列出隐藏文件

goodboy@ubuntu:~$ ls -al
total 68
drwxr-xr-x 4 goodboy goodboy 4096 Jun  8 09:32 .
drwxr-xr-x 4 root    root    4096 Jun  6 07:48 ..
-rw-rw-r-- 1 goodboy goodboy   92 Jun  7 02:44 a.c
-rw-rw-r-- 1 goodboy goodboy   12 Jun  8 09:32 a.txt
-rw------- 1 goodboy goodboy   80 Jun  6 08:18 .bash_history
-rw-r--r-- 1 goodboy goodboy  220 Jun  6 07:48 .bash_logout
-rw-r--r-- 1 goodboy goodboy 3637 Jun  6 07:48 .bashrc

chmod: 命令设置文件权限。可以用八进制数来设置权限,r-- = 4 -w- = 2 --x = 1。可以对用户、用户组和其他用户用 + 进行添加权限,用 - 删除权限,或者直接设置权限(u用户权限 g用户组权限 o其他实体权限)。

 chmod 764 filename  #rwx rw- r-- 等于764
 chmod u=rwx g=rw o=r filename
 chmod o+x filename

file :令打印文件类型信息。(-b打印不包括文件名在内的文件类型信息)

goodboy@ubuntu:~$ file /bin/grep 
/bin/grep: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=9780fb82e027800459e20af35f65055688a3c031, stripped
goodboy@ubuntu:~$ file a.c
a.c: C source, ASCII text

find:沿着文件层次结构向下遍历,匹配符合条件的文件,执行相应的操作。常用命令:-name匹配文件名,-path将路径作为一个整体匹配, -maxdepth n指定搜索层次深度,-type 按类型,按**-atime访问时间/-mtime内容修改时间/-ctime 元数据最后修改时间,-size按大小。也可以使用否定参数!反向匹配,-o/-a 多条件组合,-exec** 追加执行命令(-exec命令{} \ ;其中;前斜杠为前缀以防解释),类似xargs。

find . -name "*.txt" #从当前位置开始遍历查找 全部扩展为txt的文件,-iname为忽略大小写
find . \( -name "*.txt" -o -name "*.c" \) # 多条件,-o表示逻辑或 -a逻辑与
find . -path "*hwj*" #从当前位置开始遍历查找 完整路径中包含hwj字符串的 文件/文件夹
find . -type d -print # 列出全部目录
find . -type f -atime +7 #列出访问时间大于7天的全部文件,-7最近7天,7刚好7天前。
find . -type f -size -2k #小于2KB的文件
find . -type f -exec file {} \; # 找到每个文件,并对它们执行file查询动作(每次一个)
4.3 文件内容查看 全部cat / 按页more / 前几行head/ 尾几行tail / 二进制od

cat :cat file1 file2 file3接文件 打印到标准输出。(常用额外命令: -s 删除多余空行 -n带行号)。相比cat把全部文件内容输出,head和tail可以只查看头部和尾部一小部分文件内容,默认10行,可以-n 【行数】 指定内容。

4.4 文件统计 wc(行/单词/字符)

wc :统计文件的行数、单词数和字符数。可以通过选项打印单独一种,-l 行数,-w 单词数,-c 字符数。

goodboy@ubuntu:~$ find . -name "*.c" | xargs wc
 0  0  0 ./b.c
 6 11 92 ./a.c
 6 11 92 total
4.5 文件与重定向<、>和>>

把标准输入(stdin)、标准输出(stdout)和标准错误(stderr)通过内容过滤将输出 重定向到文件常用操作。
输入重定向 [n默认0] :就是将标准输入从文本或者标准数据流中,输入到shell命令中。
输出重定向 [n默认1]>[|]word:就是将shell的输出内容从窗口打印输出到文件中(会清空原有内容)。
扩展输出重定向 [n默认1]>>word:将shell的命令输出流重新定向到文件的后面去,不会删除原有文件的内容;

goodboy@ubuntu:~$ echo "this is a sample text" > tmp.txt
goodboy@ubuntu:~$ cat tmp.txt 
this is a sample text
goodboy@ubuntu:~$ echo "this is a second sample text" >> tmp.txt 
goodboy@ubuntu:~$ cat tmp.txt 
this is a sample text
this is a second sample text

异常输出 重定向 与重定向绑定 :重定向默认都是 标准输出,cmd > file 和 cmd 1 > file 是相同 的(异常信息还是会输出到终端),如果需要把异常输出 重定向 到文件(常见编译时需要把错误信息导出),可以使用 cmd 2 > file。cmd 2>stderr.txt 1>stdout.txt 可以分别输入到两个文件。如果希望将标准和异常输出都导入一个文件,使用 cmd 2>&1 output.txt 或者 cmd &> output.txt (重定向绑定,将stderr转换成stdout使得stderr和stdout都被重定向到同一个文件中)

goodboy@ubuntu:~$ ls +
ls: cannot access +: No such file or directory
goodboy@ubuntu:~$ ls + 2> tmp.txt 
goodboy@ubuntu:~$ cat tmp.txt 
ls: cannot access +: No such file or directory

输出 丢弃,重定向到null :cmd 2>/dev/null 会将异常输出到null空文件,相当于把输出丢弃掉,不会输出到终端。

4.6 文件比较 comm 差异diff 与 补丁patch

comm :可用于两个文件之间的比较,可以 交集、求差(difference)以及差集操作。(是comm必须使用排过序的文件作为输入)如果不附带选项,程序会生成三列输出。第一列包含文件1 特有的行,第二列包含 文件2 特有的行,而第三列包含两个文件共有的行。选项命令:-1 不输出文件1 特有的行 -2 不输出文件2 特有的行 -3 不输出两个文件共有的行

goodboy@ubuntu:~$ cat a.txt
123
456
789
goodboy@ubuntu:~$ cat b.txt
234
456
goodboy@ubuntu:~$ comm a.txt b.txt 
123
	234
		456
789

diff与patch:diff生成两个文件差异,选项-u用于生成一体化输出。可读性更好,更易于看出两个文件之间的差异,以 + 起始的是新加入的行,以 - 起始的是删除的行。用patch命令将修改应用于任意文件,当应用于version1.txt时,我们就可以得到version2.txt;而当应用于version2.txt时,就可以得到version1.txt。

 diff -u version1.txt version2.txt > version.patch #修补文件可以通过将diff的输出重定向到一个文件来生成
 patch -p1 version1.txt < version.patch #version1.txt的内容现在和verson2.txt的内容一模一样
4.7 文件 归档打包与压缩 tar

tar:可以对文件进行归档,可以将多个文件和文件夹保存为单个文件,同时还能保留所有的文件属性,如所有者、权限等。附加参数:-v 冗长模式,在归档或列出归档文件列表时获知更多的细节信息。
创建归档:tar -cf output.tar file1 file2 file3 folder1 …
拼接两个归档文件 : tar -Af file1.tar file2.tar
查询归档中文件:tar -tf archive.tar
提取内容: tar -xf archive.tar -C /path/to/extraction_directory # 不用-C路径会默认到当前目录。

压缩tar归档文件:tar命令只能用来对文件进行归档,它并不具备压缩功能。出于这个原因,多数用户在使用归档文件时都会对文件采用某种形式的压缩。-j指定bunzip2格式(file.tar.bz2) -z指定gzip格式(file.tar.gz) --lzma指定lzma格式(file.tar.lzma)

goodboy@ubuntu:~$ tar -zcvf ./tmp.tar.gz tmp.txt 
tmp.txt
goodboy@ubuntu:~$ ls -l tmp.tar.gz tmp.txt 
-rw-rw-r-- 1 goodboy goodboy  169 Jun  9 09:45 tmp.tar.gz
-rw-rw-r-- 1 goodboy goodboy 9021 Jun  9 09:44 tmp.txt
goodboy@ubuntu:~$ tar -xzvf ./tmp.tar.gz -C tmp/
tmp.txt
4.8 目录相关 创建mkdir/删除 rmdir / 切换cd /打印目录输tree

tree:tree命令以图形化的树状结构打印文件和目录。(在Linux发行版中通常并没有包含这个命令, 需要自己安装),可选项:-h 同时打印文件和目录的大小

4.9 【高阶技巧】通过网络传输文件 ftp/ setp/ rsync/ scp

五、文本相关 命令 和 技巧

字段分隔符(Internal Field Separator,IFS):把单个数据流划分成不同数据元素的定界符。内部字段分隔符是用于特定用途的定界符。IFS是存储定界符的环境变量(默认定界字符串)。

5.2 文件搜索文本 grep

grep:在 文件\标准输出 中进行搜索是文本处理,能够接受正则表达式。附加参数:-n带行号 -r递归 -o只输匹配到的文本部分 -i忽略大小写 -e多个pattern匹配 --include指定文件 --exclude排除文件 -l输出匹配文件 -E使用扩展正则表达式(或者用egrep一样) -v将匹配结果进行反转,除此之外的行 -c只是统计匹配行的数量,打印匹配附近行: -A [行数]之后 内容, -B 之前内容, -C前后内容

goodboy@ubuntu:~$ echo this is a line. | grep -E -o "[a-z]+\." 
line.
goodboy@ubuntu:~$ echo -e "1 2 3 4\nhello\n5 6" | egrep -o "[0-9]" | wc -l
6
goodboy@ubuntu:~$ echo this is a line of text | grep -e "this" -e "line" -o
this
line
goodboy@ubuntu:~$ grep -nr "main" --include '*.c'
a.c:2:int main(void) {

grep的静默输出:有时候并不打算查看匹配的字符串,而只是想知道是否能够成功匹配。这可以通过-q来实现。如果命令运行成功会返回0,如果失败则返回非0值。

goodboy@ubuntu:~$ grep -q "main" a.c 
goodboy@ubuntu:~$ echo $?
0
goodboy@ubuntu:~$ grep -q "xxmain" a.c 
goodboy@ubuntu:~$ echo $?
1
5.3 文本切分 cut 与 合并 paste

cut:将文本按列进行切分的工具。-b 表示字节 -c 表示字符 -f 用于定义字段( 要指定字段的定界符,使用 -d选项)。N- 从第N个到尾 / N-M 从第N个第M个 / -M 第1个到第M个。

cut -f 2,3 filename #显示第2列和第3列
$ cat delimited_data.txt 
No;Name;Mark;Percent 
1;Sarath;45;90 
2;Alex;49;98 
3;Anu;45;90 
$ cut -f2 -d";" delimited_data.txt 
Name 
Sarath 
Alex 
Anu
5.4 文本替换与修改 流编辑器sed

sed是流编辑器(stream editor)的缩写。配合正则表达式,可以实现大量工作,举例如下:
替换给定文本中的字符串: sed ‘s/pattern/replace_string/g’ file #s为替换,如果不加g只会提换行的第一个。
移除空白行:sed ‘/^$/d’ file #d为删除
在文件中操作(修改原文件):sed ‘s/PATTERN/replacement/’ -i filename #-i为修改原文件。
已匹配字符串标记&:可以用 &标记匹配样式的字符串,这样就能够在替换字符串时使用已匹配的内容。

goodboy@ubuntu:~$ echo this is an example | sed 's/\w\+/[&]/g' #配每一个单词,然后我们用[&]替换它
[this] [is] [an] [example]

子串匹配标记(\1):可以匹配给定样式的其中一部分,(pattern)用于匹配子串。模式被包
括在使用斜线转义过的()中。对于匹配到的第一个子串,其对应的标记是 \1,匹配到的第二个
子串是 \2,往后依次类推。

goodboy@ubuntu:~$ echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
this is 7 in a number
goodboy@ubuntu:~$ echo seven EIGHT | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
EIGHT seven
5.5【高阶技巧】高级文本处理 数据流处理器awk(暂略 )

你可能感兴趣的:(语言语法类)