YellowAndGreen YellowAndGreen
首页
  • 闲谈大学淘书之旅
  • 考研有感
读书
  • 技术文档
  • GitHub技巧
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

黄不盈

道冲而用之或不盈
首页
  • 闲谈大学淘书之旅
  • 考研有感
读书
  • 技术文档
  • GitHub技巧
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 实用仓库

  • 技术文档

  • GitHub技巧

  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
    • Shell指令
      • 基础
        • 复合命令
        • 常用命令
        • find
        • xargs
      • 权限
      • 重定向
      • 进程
      • 变量
      • Shell Scripts
        • if else
        • function
        • while
      • 文本处理
        • 通配符
        • cut
        • grep
        • 基本用法
        • 示例
        • 正则表达式
        • 管道使用
        • 注意事项
        • sed
        • 常用指令
        • 常用选项
        • 替换指令(s)
        • 打印指令(p)
        • 删除指令(d)
        • 插入和追加指令(i 和 a)
        • 模式匹配
        • 实例
        • 多行模式
        • awk
        • 基本语法
        • 比较操作符
        • 脚本示例
        • 复杂脚本示例
        • 模式匹配
        • 内置数组
        • 流程控制
        • 多文件处理
  • 技术
  • 学习笔记
yellowandgreen
2025-03-20
目录

Shell指令

# Shell指令

# 基础

# 复合命令

在Shell脚本中,复合命令是由多个简单命令组合而成的命令,它们可以是管道(pipe),列表(list),条件语句(conditional),循环语句(loops),函数(functions)等。以下是一些常见的Shell复合命令类型:

  1. 管道(Pipe):

    command1 | command2
    
    1

    管道允许将一个命令的输出作为另一个命令的输入。

  2. 列表(List):

    command1; command2
    
    1

    列表允许你按顺序执行多个命令,每个命令在前一个命令完成后执行。

# 常用命令

ls -a -F  # 显示所有文件,文件夹后面带/
cat test.txt -n  # 输出文件内容并表明行号
mkdir -p /bin/test/a  # 创建所有需要的目录
cp -r /bin/a /bin/b  # 拷贝目录
mv docs/ bin/ a.txt dst/  # 将多个目录和文件移动到dst目录中
ls -l test.txt  # 显示详细信息以判断文件类型,权限等
echo "aaa"     # 输出文本
echo -e "aaa\n"  # 使符号起作用

OUTPUT = "> out.file"
eval echo hello $OUTPUT  # eval让Shell第二次重新处理命令行

expr 3+2   # 执行简单的整数算术运算
touch a.txt  #  创建新文件

# 命令别名
alias lm='ls -al | more'
unalias lm  # 取消别名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

符号链:

# 创建指向文件的符号链:
ln -s target_file symlink_name
# 创建指向目录的符号链:
ln -s target_directory symlink_directory
# 例如在同一个文件夹下存在test1和test2,需要将test1中的文件链接到test2中:
ln -s ../test1/a.txt ./test2/b.txt
1
2
3
4
5
6

# find

Linux 中的 find 命令是一个非常强大的工具,用于在指定目录及其子目录下查找符合条件的文件或目录。以下是 find 命令的一些基本用法和选项:

  1. 基本语法:

    find [path] [options] [actions]
    
    1
    • path:指定搜索的起始目录,默认为当前目录(.)。
    • expression:定义搜索条件。
  2. 常用选项:

    • -name:按文件名查找文件。例如 -name "*.txt" 查找所有以 .txt 结尾的文件。
    • -type:查找文件类型,可以是 f(文件)、d(目录)等。
    • -size:按文件大小查找文件,例如 -size +10M 查找大于 10MB 的文件。
    • -mtime:按文件内容最后修改时间查找文件,单位是天。例如 -mtime -7 查找过去 7 天内修改过的文件。
    • -atime:按文件最后访问时间查找文件。
    • -ctime:按文件状态最后改变时间查找文件。
    • -user:按文件所有者查找文件。
    • -group:按文件所属组查找文件。
    • -mindepth 和 --depth:控制搜索的深度。
    • -exec:对找到的每个文件执行指定的命令。例如 -exec rm {} \; 删除找到的每个文件。
    • -print:打印找到的文件名(默认行为)。
    • -maxdepth 和 -mindepth:限制搜索的深度。
  3. 组合使用: find 命令可以结合逻辑运算符来使用,如 -o(或)和 -not(非)。

    • -o:表示逻辑或,例如 -name "*.txt" -o -name "*.pdf" 查找所有 .txt 或 .pdf 文件。
    • -not:表示逻辑非,例如 -not -name "*.tmp" 查找所有非 .tmp 文件。
  4. 使用正则表达式: 在某些版本的 find 中,可以使用 -path 选项来使用正则表达式匹配路径。

  5. 使用 find 命令的示例:

    • 查找当前目录及其子目录下所有 .txt 文件:
      find . -name "*.txt"
      
      1
    • 查找 /var/log 目录下 7 天内未修改的文件并删除:
      find /var/log -type f -mtime +7 -exec rm {} \;
      
      1
    • 查找 /home/user 目录下所有属于用户 user 的文件:
      find /home/user -user user
      
      1

# xargs

xargs能够读取标准输入(stdin)数据,将其转换为命令行参数,并执行相应的命令。xargs 常用于与管道(pipe)一起使用,将一个命令的输出作为另一个命令的输入。

以下是 xargs 的一些关键特性和选项:

  1. 基本用法:

    command | xargs [options] [command]
    
    1

    这里,command 是生成输入数据的命令,xargs 读取这些数据,并将其作为参数传递给后面的 command。

  2. 常用选项:

    • -0 或 --null:使用 null 字符作为输入项的分隔符,通常与 find 命令的 -print0 选项一起使用,适用于文件名包含空格或特殊字符的情况。
    • -a:从每个给定的文件中读取输入项,直到文件结束。
    • -I {}:指定替换字符串 {},xargs 会用输入项替换 {} 并执行命令。例如:
      echo -e "one\ntwo" | xargs -I {} echo "Item: {}"
      
      1
      输出将是:
      Item: one
      Item: two
      
      1
      2
    • -n [number] 或 --max-args [number]:指定每次调用命令时使用的最大参数数量,默认为每个命令一行。
    • -P [number] 或 --max-procs [number]:指定同时运行的最大进程数。
    • -p:在执行命令前提示用户确认。
    • --max-chars [number] 或 -x:指定每个命令行的最大字符数,超过这个数将自动换行。
    • -r:如果输入为空,则不执行命令。
    • -t:在执行命令之前打印命令和参数。
  3. 使用示例:

    • 使用 find 和 xargs 删除当前目录下所有 .tmp 文件:
      find . -type f -name "*.tmp" -print0 | xargs -0 rm -f
      
      1
    • 将当前目录下所有 .txt 文件复制到 /backup 目录:
      find . -type f -name "*.txt" | xargs -I {} cp {} /backup
      
      1
    • 并行执行 tar 压缩当前目录下所有 .tar 文件,同时运行的最大进程数为 4:
      find . -type f -name "*.tar" | xargs -P 4 -I {} tar -czvf {}.tar.gz {}
      
      1
  4. 注意事项:

    • 当使用 xargs 时,如果输入数据中包含特殊字符或空格,可能会引起问题。使用 -0 和 -print0 选项可以避免这类问题。
    • 使用 -p 选项可以增加交互性,每次执行前都会提示用户确认。
    • 使用 -n 选项可以控制每次调用命令时的参数数量,有助于防止命令行过长。

# 权限

以三个为一组,且均为『rwx』 的三个参数的组合。其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]。

[!NOTE]

目录必须给到r和x才能切换到目录中去。

  • chgrp :改变档案所属群组

    [root@study ~]# chgrp [-R] dirname/filename ...
    选项与参数:
    -R : 进行递迴(recursive)的持续变更,亦即连同次目录下的所有档案、目录
         都更新成为这个群组之意。常常用在变更某一目录内所有的档案之情况。
    范例:
    [root@study ~]# chgrp users initial-setup-ks.cfg
    [root@study ~]# ls -l
    -rw-r--r--. 1 root users 1864 May  4 18:01 initial-setup-ks.cfg
    [root@study ~]# chgrp testing initial-setup-ks.cfg
    chgrp: invalid group:  `testing' <== 发生错误讯息啰~找不到这个群组名~
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • chown :改变档案拥有者

    [root@study ~]# chown [-R] 帐号名称 档案或目录
    [root@study ~]# chown [-R] 帐号名称:群组名称 档案或目录
    选项与参数:
    -R : 进行递迴(recursive)的持续变更,亦即连同次目录下的所有档案都变更
    
    范例:将 initial-setup-ks.cfg 的拥有者改为bin这个帐号:
    [root@study ~]# chown bin initial-setup-ks.cfg
    [root@study ~]# ls -l
    -rw-r--r--. 1 bin  users 1864 May  4 18:01 initial-setup-ks.cfg
    
    范例:将 initial-setup-ks.cfg 的拥有者与群组改回为root:
    [root@study ~]# chown root:root initial-setup-ks.cfg
    [root@study ~]# ls -l
    -rw-r--r--. 1 root root 1864 May  4 18:01 initial-setup-ks.cfg
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  • chmod :改变档案的权限, SUID, SGID, SBIT等等的特性

    • 使用数字类型,r:4,w:2,x:1

      [root@study ~]# ls -al .bashrc
      -rw-r--r--. 1 root root 176 Dec 29  2013 .bashrc
      [root@study ~]# chmod 777 .bashrc
      [root@study ~]# ls -al .bashrc
      -rwxrwxrwx. 1 root root 176 Dec 29  2013 .bashrc
      
      1
      2
      3
      4
      5
    • 符号类型改变档案权限

      chmod u g o a +(加入) -(除去) =(设定) r w x 档案或目录
      [root@study ~]# chmod  u=rwx,go=rx  .bashrc
      [root@study ~]# chmod  a+w  .bashrc
      
      1
      2

# 重定向

# 使用符号 2>&1 将标准错误(stderr)重定向到标准输出(stdout)。
command 2>&1 output.txt
command > output.txt 2>&1
1
2
3

# 进程

long_running_process &
1

这会将 long_running_process 放入后台执行,Shell会立即显示新的提示符。

使用ctrl + z将前台程序悬挂,然后使用bg %1将其移入后台,实用fg %1将其移入前台。

使用jobs显示悬挂的进程或者后台进程。使用ps -f显示当前终端进程,使用ps -e显示所有进程。

使用ps aux显示所有进程的详细信息。

使用top显示实时进程

例子:

ps aux | grep rosbag/record | grep -v grep | awk '{print $2}' | xargs kill -SIGINT

  • kill 命令用于发送信号给进程,-SIGINT 选项指定发送 SIGINT 信号,这通常是Ctrl+C的信号,用于请求进程优雅地终止。
  • pgrep python | xargs kill -2:pgrep命令用于搜索当前运行的进程列表,并根据指定的条件列出匹配的进程的进程ID(PID),-2用于ctrl+c终止

# 变量

# 标准的变量引用
echo $HOME

# 使用花括号,即使变量为空,也不会报错
echo ${HOME}

# 使用花括号提供默认值
echo ${HOME:-"/default/home/directory"}

# 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
『var="lang is $LANG"』则『echo $var』可得『lang is en_US』
# 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:
『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』

# 取消变量
unset var

# 累加变量
PATH=${PATH}:/home/dmtsai/bin

# 查看所有环境变量
env
# 所有变量
set

# 显示当前进程PID,$变量表征
echo $$
# 上一个运行的命令所回传的值,?表示回传值
echo $?
# 表示所有传递给脚本或命令的参数
echo $*
# 表示传递给脚本或命令的参数个数
echo $#
# 将自定义变量变成环境变量
export 变量名称

# 双括号可直接使用变量,且执行算数运算
echo $((a+b))  # 输出加和3
((a = 5 < 10 && 10 > 1))
echo a

# 定义类型
[root@www ~]# declare [-aixr] variable
选项与参数:
-a  :将后面名为 variable 的变量定义成为数组 (array) 类型
-i  :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x  :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r  :将变量配置成为 readonly 类型,该变量不可被更改内容,也不能 unset

范例一:让变量 sum 进行 100+300+50 的加总结果
[root@www ~]# sum=100+300+50
[root@www ~]# echo $sum
100+300+50  <==咦!怎么没有帮我计算加总?因为这是文字型态的变量属性啊!
[root@www ~]# declare -i sum=100+300+50
[root@www ~]# echo $sum
450
范例二:将 sum 变成环境变量
[root@www ~]# declare -x sum
[root@www ~]# export | grep sum
declare -ix sum="450"  <==果然出现了!包括有 i 与 x 的宣告!

范例三:让 sum 变成只读属性,不可更动!
[root@www ~]# declare -r sum
[root@www ~]# sum=tesgting
-bash: sum: readonly variable  <==老天爷~不能改这个变量了!

范例四:让 sum 变成非环境变量的自定义变量吧!
[root@www ~]# declare +x sum  <== 将 - 变成 + 可以进行『取消』动作
[root@www ~]# declare -p sum  <== -p 可以单独列出变量的类型
declare -ir sum="450" <== 看吧!只剩下 i, r 的类型,不具有 x 啰!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

# Shell Scripts

[!TIP]

利用直接运行(sh xxx.sh)的方式来运行 script和利用 source 来运行结果不同。前者是在子程序中运行,因此子程序中的变量在父程序中不存在,而后者完全在父程序中运行。

# if else

if [[ ! "$algorithmType" =~ "fusion" ]];then
    type_pre='lidar' # 使用正则判断
fi
if [ "$algorithmType" == "prediction" ]; then
1
2
3
4

# function

add_numbers() {
  echo $(( $1 + $2 ))
}

# 调用函数
result=$(add_numbers 3 5)
echo "Result is $result"
1
2
3
4
5
6
7

# while

while [ condition ]  <==中括号内的状态就是判断式
do            <==do 是回圈的开始!
	程序段落
done          <==done 是回圈的结束


until [ condition ]
do
	程序段落
done
1
2
3
4
5
6
7
8
9
10

for

for var in con1 con2 con3 ...
do
	程序段
done

for (( i=1; i<=$nu; i=i+1 ))
do
	s=$(($s+$i))
done
echo "The result of '1+2+3+...+$nu' is ==> $s"
1
2
3
4
5
6
7
8
9
10

# 文本处理

head -n  # 输出前n行
tail -n  # 输出后n行
ls -1ut  # 输出当前文件夹下的所有东西,分行显示,同时按照时间修改排序。-u表示以最新为首,无则反之。-t表示按时间修改。
tail -f  # 强制查看,能够看到被写入的文件比如log
1
2
3
4

# 通配符

符号 意义
* 代表『 0 个到无穷多个』任意字符
? 代表『一定有一个』任意字符
[ ] 同样代表『一定有一个在括号内』的字符(非任意字符)。例如 [abcd] 代表『一定有一个字符, 可能是 a, b, c, d 这四个任何一个』
[ - ] 若有减号在中括号内时,代表『在编码顺序内的所有字符』。例如 [0-9] 代表 0 到 9 之间的所有数字,因为数字的语系编码是连续的!
[^ ] 若中括号内的第一个字符为指数符号 (^) ,那表示『反向选择』,例如 [^abc] 代表 一定有一个字符,只要是非 a, b, c 的其他字符就接受的意思。

接下来让我们利用通配符来玩些东西吧!首先,利用通配符配合 ls 找檔名看看:


[root@www ~]# LANG=C              <==由于与编码有关,先配置语系一下

范例一:找出 /etc/ 底下以 cron 为开头的档名
[root@www ~]# ll -d /etc/cron*    <==加上 -d 是为了仅显示目录而已

范例二:找出 /etc/ 底下文件名『刚好是五个字母』的文件名
[root@www ~]# ll -d /etc/?????    <==由于 ? 一定有一个,所以五个 ? 就对了

范例三:找出 /etc/ 底下文件名含有数字的文件名
[root@www ~]# ll -d /etc/*[0-9]*  <==记得中括号左右两边均需 *

范例四:找出 /etc/ 底下,档名开头非为小写字母的文件名:
[root@www ~]# ll -d /etc/[^a-z]*  <==注意中括号左边没有 *

范例五:将范例四找到的文件复制到 /tmp 中
[root@www ~]# cp -a /etc/[^a-z]* /tmp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

除了通配符之外,bash 环境中的特殊符号有哪些呢?底下我们先汇整一下:

符号 内容
# 批注符号:这个最常被使用在 script 当中,视为说明!在后的数据均不运行
\ 跳脱符号:将『特殊字符或通配符』还原成一般字符
| 管线 (pipe):分隔两个管线命令的界定(后两节介绍);
; 连续命令下达分隔符:连续性命令的界定 (注意!与管线命令并不相同)
~ 用户的家目录
$ 取用变量前导符:亦即是变量之前需要加的变量取代值
& 工作控制 (job control):将命令变成背景下工作
! 逻辑运算意义上的『非』 not 的意思!
/ 目录符号:路径分隔的符号
>, >> 数据流重导向:输出导向,分别是『取代』与『累加』
<, << 数据流重导向:输入导向 (这两个留待下节介绍)
' ' 单引号,不具有变量置换的功能
" " 具有变量置换的功能!
两个『 ` 』中间为可以先运行的命令,亦可使用 $( )
( ) 在中间为子 shell 的起始与结束
{ } 在中间为命令区块的组合!

# cut

[dmtsai@study ~]$ cut -d'分隔字元' -f fields <==用于有特定分隔字元
[dmtsai@study ~]$ cut -c 字元区间            <==用于排列整齐的讯息
选项与参数:
-d  :后面接分隔字元。与 -f 一起使用;
-f  :依据 -d 的分隔字元将一段讯息分割成为数段,用 -f 取出第几段的意思;
-c  :以字元 (characters) 的单位取出固定字元区间;

范例一:将 PATH 变数取出,我要找出第五个路径。
[dmtsai@study ~]$ echo ${PATH}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
#      1      |    2   |       3       |    4    |           5           |      6         |

[dmtsai@study ~]$ echo ${PATH} | cut -d ':' -f 5
# 如同上面的数字显示,我们是以『 : 』作为分隔,因此会出现 /home/dmtsai/.local/bin
# 那么如果想要列出第 3 与第 5 呢?,就是这样:
[dmtsai@study ~]$ echo ${PATH} | cut -d ':' -f 3,5

范例二:将 export 输出的讯息,取得第 12 字元以后的所有字串
[dmtsai@study ~]$ export
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/home/dmtsai"
declare -x HOSTNAME="study.centos.vbird"
.....(其他省略).....
# 注意看,每个资料都是排列整齐的输出!如果我们不想要『 declare -x 』时,就得这么做:

[dmtsai@study ~]$ export | cut -c 12-
HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/home/dmtsai"
HOSTNAME="study.centos.vbird"
.....(其他省略).....
# 知道怎么回事了吧?用 -c 可以处理比较具有格式的输出资料!
# 我们还可以指定某个范围的值,例如第 12-20 的字元,就是 cut -c 12-20 等等!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# grep

grep 是一个强大的文本搜索工具,用于在文件中搜索匹配特定模式的行。以下是 grep 命令的一些关键特性和用法:

# 基本用法

  • grep pattern [file...]:在指定的文件中搜索包含 pattern 的行。

选项:

  • -i:忽略大小写。搜索时不区分大写和小写字母。
  • -v:反向搜索。只打印不匹配 pattern 的行。
  • -r 或 --recursive:递归地在所有文件和目录中搜索。
  • -l:只打印包含匹配行的文件名。
  • -n:显示匹配行的行号。
  • -c:仅显示匹配行的数量,不显示行本身。
  • --color:将匹配的文本高亮显示(通常是彩色的)。
  • -e:使用多个搜索模式。
  • -w 或 --word-regexp:仅匹配整个单词。
  • --line-buffered:使用行缓冲,确保输出即时显示,即使输出被管道传输。

# 示例

  • 搜索包含 "error" 的行:
    grep "error" logfile.txt
    
    1
  • 忽略大小写搜索 "error":
    grep -i "error" logfile.txt
    
    1
  • 打印不包含 "error" 的行:
    grep -v "error" logfile.txt
    
    1
  • 递归搜索目录中的所有文件:
    grep -r "pattern" /path/to/directory
    
    1
  • 只打印包含 "error" 的文件名:
    grep -l "error" /path/to/directory
    
    1
  • 显示匹配行的行号:
    grep -n "error" logfile.txt
    
    1
  • 显示匹配行的数量:
    grep -c "error" logfile.txt
    
    1
  • 高亮显示匹配的文本:
    grep --color "error" logfile.txt
    
    1
  • 使用多个搜索模式:
    grep -e "error" -e "warning" logfile.txt
    
    1
  • 仅匹配整个单词 "error":
    grep -w "error" logfile.txt
    
    1

# 正则表达式

grep 支持基本的正则表达式,允许进行更复杂的搜索模式匹配。例如:

  • 搜索以 "log" 开头的行:
    grep "^log" logfile.txt
    
    1
  • 搜索包含数字的行:
    grep "[0-9]" logfile.txt
    
    1

# 管道使用

grep 经常与其他命令结合使用,通过管道传递数据。例如,使用 cat 查看文件并搜索包含特定文本的行:

cat largefile.txt | grep "pattern"
1

# 注意事项

  • 默认情况下,grep 区分大小写,除非你使用 -i 选项。
  • 使用复杂的正则表达式时,可能需要根据Shell的不同使用引号或转义字符。
  • 在某些系统中,grep 的默认行为可能因版本或配置而异,例如,是否默认启用颜色输出。

# sed

sed(Stream Editor)是一个功能强大的Unix-like命令行工具,用于对文本数据进行过滤和替换。以下是 sed 的一些基本用法和概念:

# 基础构造,script为具体模型和动作,如/pattern/action,表示在pattern下搜索到时的动作。files表示一个或多个文件。
sed 'script' files
1
2

sed 的基本语法如下:

sed [选项] '指令' 文件
1

其中,[选项] 是可选的,[指令] 是必需的,文件 是要处理的文本文件。

# 常用指令

  • s:替换指令,用于替换文本。
  • d:删除指令,用于删除匹配的行。
  • p:打印匹配成功的行

# 常用选项

  • -n:仅打印经过 sed 处理的行。
  • -e:允许在命令行上执行多个 sed 命令,例如:sed -e 'script1' -e 'script2'.
  • -i:直接修改文件内容,而不是输出到标准输出,例如:sed -i 's/old/new/g' filename。

# 替换指令(s)

替换指令的基本格式如下:

s/old/new/
1

这将把所有的 "old" 替换为 "new"。使用 g 标志可以实现全局替换:

s/old/new/g
1

[!IMPORTANT]

在s命令中可以使用&在new中重用old中的匹配结果:sed 's/ab/$ab/g' test.txt

# 打印指令(p)

会打印出所有的行和匹配的结果,使用-n只输出匹配结果

/pattern/p
1

# 删除指令(d)

删除指令可以删除匹配特定模式的行:

/pattern/d
1

# 插入和追加指令(i 和 a)

插入和追加指令可以在指定模式匹配的行之前或之后添加文本:

i\
这是插入的文本
a\
这是追加的文本
1
2
3
4

注意:在 i 和 a 指令后面需要使用 \ 来表示多行文本。

# 模式匹配

sed 支持基本的正则表达式进行模式匹配。例如:

s/[0-9]+/数字/g
1

这将把所有的数字替换为 "数字"。

# 实例

  • 将文件中的 "old" 替换为 "new" 并输出结果:
    sed 's/old/new/g' filename
    
    1
  • 直接在文件中替换文本(原地编辑):
    sed -i 's/old/new/g' filename
    
    1
  • 删除包含 "error" 的所有行:
    sed '/error/d' filename
    
    1
  • 在每行的末尾追加文本 " - append":
    sed 's/$/ - append/' filename
    
    1
  • 在包含 "pattern" 的行后追加文本:
    sed '/pattern/a\
    这是追加的文本' filename
    
    1
    2

# 多行模式

sed 可以处理多行模式,使用 \ 来分隔多行:

sed '/start_pattern/{
  /end_pattern/!d
}'
1
2
3

这将删除从 "start_pattern" 到 "end_pattern" 之间的所有行。

# awk

awk 是一个强大的文本处理工具,它设计用于处理结构化数据,特别是表格化数据。awk 的名称来源于它的创始人 Alfred V. Aho、Peter J. Weinberger 和 Brian W. Kernighan 的姓氏首字母。

# 基本语法

awk 的基本语法如下:

awk '/pattern/{action}' files
1

这里,条件 是可选的,如果省略则对所有行执行 动作。

变量

  • $0: 整行内容。
  • $1, $2, ...: 当前行的第1个,第2个...字段(默认字段分隔符为空白字符)。例如:awk '{print $1,$3;}' fruit.txt,其中的逗号会打印成空格。
  • NF: 当前行的字段总数。
  • NR: 已处理的记录数(行号)。

常用内置函数:

  • print及printf: 打印文本。
  • sprintf: 格式化字符串。
  • split: 将字符串分割成数组。
  • length: 返回字符串的长度。

常用选项:

  • -F: 设置输入字段分隔符。
  • -v: 设置变量的值。

# 比较操作符

以下是一些使用 awk 比较操作符的示例:

  • 检查字段是否等于特定值:

    awk '$1 == "expected_value" { print "Match found" }' data.txt
    
    1
  • 检查数值字段是否在某个范围内:

    awk '$1 >= 10 && $1 <= 20 { print "Value is within range" }' data.txt
    
    1
  • 使用正则表达式检查字段是否匹配模式:

    awk '$1 ~ /^[0-9]+$/ { print "Field contains only digits" }' data.txt
    
    1
  • 检查字段是否不匹配模式:

    awk '$1 !~ /^[a-z]+$/ { print "Field contains non-lowercase letters" }' data.txt
    
    1
  • 使用next跳过后续检查项:

    awk '
    $1 == "expected_value" { print "Match 1 found";next; }
    $2 == "expected_value" { print "Match 2 found" }
    ' data.txt
    
    1
    2
    3
    4

# 脚本示例

awk -F, '{
  if ($1 == "条件") print $2
}' filename.csv
1
2
3

这个脚本将处理 filename.csv 文件,该文件的字段由逗号分隔。如果第一字段匹配 "条件",则打印第二字段。

# 复杂脚本示例

awk '{ sum += $3 }
  END {
    if (NR > 0) print "Average:", sum / NR
  }' filename
1
2
3
4

这个脚本将计算文件中第三字段的平均值,并在处理完所有行后打印出来。

# 模式匹配

  • 使用模式匹配特定行:
    awk '/pattern/ {print $0}' filename
    
    1
  • 使用多个模式:
    awk '模式1 {动作1} 模式2 {动作2}' filename
    
    1

# 内置数组

awk 允许你使用内置数组来存储和操作数据:

awk '{ arr[$1] += $2 } END { for (key in arr) print key, arr[key] }' filename
1

这个脚本将创建一个数组 arr,其中键是第一字段,值是第二字段的累加和。

# 流程控制

awk 支持 if-else 和 while 等流程控制语句:

awk '{ if ($1 > 0) print "Positive"; else print "Non-positive" }' filename
1

# 多文件处理

awk 可以同时处理多个文件:

awk '{ ... }' file1 file2 file3
1

awk 的强大之处在于其灵活性和对复杂数据处理的支持。它可以读取、处理和生成结构化文本数据,是Unix-like系统中不可或缺的工具之一。

编辑 (opens new window)
上次更新: 2024/10/13, 16:24:43
JS设计模式总结笔记

← JS设计模式总结笔记

最近更新
01
2024游戏总结
03-20
02
2023游戏总结
03-20
03
随记1
03-20
更多文章>
Theme by Vdoing | Copyright © 2023-2025 黄不盈 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式