前端不会Shell?Shell 命令只会 cd 的小伙伴,这篇文章你真的得看了

3,148 阅读31分钟

前言

shell命令的操作和脚本开发从来都不是运维人员的专属技能,高级/资深前端工程师往往已经能够熟练使用大量shell命令来为自己提效,掌握shell命令不仅可以在服务器运维时大显身手,日常开发中也能帮你替代大量的鼠标键盘操作,本文将为你提供最全的常用 shell 命令操作速查手册。

虽然但是,你不禁还是要问

我一个前端为啥要会shell?

了解基本的 Shell 命令和脚本编写对前端开发人员来说是必要的,你看看以下几点能不能够说服你:

  1. 提高工作效率: 熟练使用shell可以大大优化前端开发者的常见操作,如文件处理、程序运行、远程连接、发起网络请求等,还可以自动化许多重复性任务,减少手动操作的错误,极大提升工作效率。

    查看本机ip?别再去网络设置里看了,用命令1s内搞定。

    如果你要上传一个文件到服务器,想一想它有多少个步骤,编写几行脚本,一个回车就能解决不香么?

    简单测试下限制10次/s的限流器是否生效,你会怎么做,试试用 shell 写个脚本,几行搞定,其他项目还能复用。

    不能说用鼠标点击很low,但是当你用习惯命令行时会发现鼠标点击真的很慢,效率很低。

  2. 掌握部署运维: 部署和运维前端项目通常需要用到shell脚本,了解shell能更好地进行自动化部署。

    这个没啥说的,掌握基本运维操作是一个高级前端应该具备的技能,可能不需要你去写部署的脚本,但是类似让你自己修改下nginx的配置这种是应该可以分分钟搞定的。

  3. 调试项目问题: 查看日志文件,检查环境变量等都需要shell命令,有助于快速定位和解决各种问题。

  4. 配合开发工具: 许多前端工具都需要配合shell命令使用,如Webpack、npm scripts、Jenkins等,当你自研脚手架或写自己的 npm 包时就更需要。

  5. 拓宽技术视野: 计算机科学中shell是非常基础和重要的知识,对前端开发有启发作用,同时也能提升你在团队的技术影响力。

命令行执行脚本时参数的传递和获取

顺序参数

假设在命令行执行以下脚本:

sh bin/start.sh -p 30128 -n myproject -e prod

其中的 -p 30128 -n myproject -e prod 即为参数传递的方式,在 start.sh 脚本中,你可以使用特殊变量 $1$2$3 等来获取命令行传入的参数。这些特殊变量分别表示第一个、第二个、第三个参数,以此类推。

例如,假设你的 start.sh 脚本内容如下:

#!/bin/bash

# 获取第一个参数值,即 -p 后面的值
PORT=$2

# 获取第二个参数值,即 -n 后面的值
NAME=$4

# 获取第三个参数值,即 -e 后面的值
ENVIRONMENT=$6

echo "Port: $PORT"
echo "Name: $NAME"
echo "Environment: $ENVIRONMENT"

echo "$@"   # 输出所有参数,每个作为一个词,整体则为数组
echo "$*"   # 输出所有参数,作为一个整体字符串

注意 $1 $2 $3 $4 $5 $6 分别对应 -p 30128 -n myproject -e prod

当你执行以上命令时:输出将会是:

Port: 30128
Name: myproject
Environment: prod

-p 30128 -n myproject -e prod
-p 30128 -n myproject -e prod

相关扩展:$ 和 @ 符号

$和@属于shell的特殊字符,用来表示传递给脚本或函数的位置参数。

具体来说:

  • $n:读取第n个位置参数的值。
  • $@:以数组的形式读取所有位置参数。
  • $*:以字符串的形式读取所有位置参数。
  • $0:当前脚本或函数的名称
  • $#:位置参数的个数
  • $$:当前Shell进程的PID

无序参数

使用 getopts 无需按照顺序获取参数

#!/bin/bash

# 使用 getopts 来解析命令行参数
# 当传入 -p、-n、-e 选项时,分别将参数值保存到 PORT、NAME、ENVIRONMENT 变量
while getopts ":p:n:e:" opt; do
  case "$opt" in
  # 如果是 -p 选项
  p)
    PORT=$OPTARG
    ;;

    # 如果是 -n 选项
  n)
    NAME=$OPTARG
    ;;

    # 如果是 -e 选项
  e)
    ENVIRONMENT=$OPTARG
    ;;

    # 如果遇到非法的选项参数,打印错误提示
  \?)
    echo "Invalid option: -$OPTARG" 1>&2
    ;;
    
    # 如果缺少参数值,自定义错误提示
  :)
    echo "Option -$OPTARG requires an argument" 1>&2
    ;;
  esac
done

# 打印出解析后的参数值
echo "Port: $PORT"
echo "Name: $NAME"
echo "Environment: $ENVIRONMENT"

相关扩展: getopts 命令

getopts是Linux/Unix系统shell脚本中处理命令行选项和参数的工具。

":p:n:e:" 是一个选项字符串,定义了可以接受哪些选项以及这些选项是否需要参数。

  • ::在选项字符串的开头表示如果 getopts 遇到一个选项需要参数,但用户没有提供参数,那么 getopts 将把该选项的名称存储在 OPTARG 变量中,并设置 opt 变量为 :。这就是为什么在 case 语句中有一个 : 分支,用于处理这种情况。另外,加上首个冒号之后代表选项参数是可选的,去掉首个冒号代表参数是必填的。
  • p:表示脚本可以接受 -p 这个选项。
  • p::后面的 : 表示这个选项需要一个参数。

在上述示例中,getopts命令后面的冒号表示参数可选,而选项字符(如pne)则是你希望解析的选项(键),会存储到 opt上。每个选项后的冒号表示这个选项可以带一个值。

getoptswhile循环中,$opt会保存当前解析到的键,而$OPTARG会保存该选项的值(如果有的话)。

如果你运行脚本时使用了未定义的选项,那么$opt会被设置为?,可以在case语句中处理未知选项。

相关扩展: >& 操作符

1>&2 是一种重定向文件描述符操作,用于将标准输出(文件描述符 1)重定向到标准错误输出(文件描述符 2)。

在 Unix 和类 Unix 系统中(去了解 Unix、Linux、 MacOs、 Bash、 Shell 之间的关系),当你运行一个命令或脚本时,它通常有三个默认的文件描述符(也就是数据流):

  • 标准输入(stdin),文件描述符为 0
  • 标准输出(stdout),文件描述符为 1
  • 标准错误输出(stderr),文件描述符为 2

所以,1>&2 的意思就是将标准输出重定向到标准错误输出。这样,原本会打印到屏幕或被重定向到文件的输出信息,现在会被打印到标准错误输出,在你希望将错误信息和正常输出分开处理时非常有用。

echo "Option -$OPTARG requires an argument" 1>&2 这行代码就是将错误消息 “Option -$OPTARG requires an argument” 打印到标准错误输出,而不是标准输出。这样,如果用户将脚本的输出重定向到文件,这个错误消息仍然会被打印到屏幕,而不会被写入文件。

为了方便理解,举个例子:

假设我们有一个名为 myscript.sh 的 Bash 脚本,内容如下:

echo "This is a normal message."
echo "This is an error message." 1>&2

这个脚本会打印两条消息,一条是正常的消息,另一条是错误消息。

如果我们直接运行这个脚本,那么两条消息都会被打印到终端:

$ ./myscript.sh
This is a normal message.
This is an error message.

但是,如果我们将脚本的输出重定向到文件,那么只有正常的消息会被写入文件,错误消息仍然会被打印到终端:

$ ./myscript.sh > output.txt
This is an error message.

然后,如果我们查看 output.txt 文件的内容,我们只会看到正常的消息:

$ cat output.txt
This is a normal message.

这就是 1>&2 的作用:即使你将脚本的输出重定向到文件,错误消息仍然会被打印到终端

相关扩展:用于输出的命令和操作符:echo、printf、>、>>、tee

  1. echoecho 是一个内置命令,用于在标准输出(通常是终端)上打印一行文本。例如:

    echo "Hello, world!"
    

    这条命令会在终端上打印 “Hello, world!”

    echo 会默认显示特殊字符和转义字符

    • 显示特殊字符和转义字符:
    echo "This is a line with a newline character.\nAnd this is the second line."
    

    未加引号时 echo 会自动合并多个空格为一个,加引号会保留多个空格

    • 显示特殊字符(不解释转义字符):
    echo -E "This is a line with a backslash followed by an 'n'.\nAnd this is the second line."
    
    • 显示多个参数:
    echo "Item 1" "Item 2" "Item 3"
    
  2. printfprintf 是一个更强大的内置命令,可以格式化输出文本。例如:

    printf "Hello, world!\n"
    
    printf "Hello, %s!\n" "world"
    

    这条命令会在终端上打印 “Hello, world!”。%s 是一个占位符,表示一个字符串,\n 表示新行。

    当使用格式化字符串时,printf 会保留换行空格等特殊字符,这在你需要保持原始字符串或者json数据时很有用。

    name="Hello,\nworld!"
    printf "Hello, %s!" "$name"
    
    # 输出
    # Hello, Hello,\nworld!!
    
  3. >> 是一个重定向操作符,用于将标准输出重定向到文件。如果文件已存在,则会覆盖文件的内容。例如:

    echo "Hello, world!" > file.txt
    

    这条命令会将 “Hello, world!” 写入 file.txt,覆盖 file.txt 中的任何现有内容。

  4. >>>> 也是一个重定向操作符,与 > 类似,但如果文件已存在,则会将内容追加到文件的末尾,而不是覆盖现有内容。例如:

    echo "Hello, again!" >> file.txt
    
    # 多个文件
    echo "Some text" >> file1.txt >> file2.txt
    

    这条命令会将 “Hello, again!” 追加到 file.txt 的末尾。

  5. teetee 是一个命令,可以将输入同时发送到标准输出和一个或多个文件。例如:

    echo "Hello, world!" | tee file.txt
    

    这条命令会在终端上打印 “Hello, world!”,并将其写入 file.txt。如果你希望追加内容而不是覆盖,你可以使用 -a 选项:

    echo "Hello, again!" | tee -a file.txt
    

    输出到多个文件

    echo "Hello, world!" | tee file1.txt file2.txt file3.txt
    

快速获取本机 ip 地址

ifconfig | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}'
  • ifconfig:这个命令用于显示和配置网络接口的信息,包括 IP 地址、MAC 地址等。

  • |:管道操作符,它将前一个命令的输出作为后一个命令的输入。在这个命令中,ifconfig 的输出将作为后续命令的输入。

  • grep inet:使用 grep 工具来搜索包含 "inet" 的行,这些行包含了 IP 地址的信息,例如:

    inet 127.0.0.1 netmask 0xff000000
    inet6 ::1 prefixlen 128
    inet6 fe0::1%lo0 prefixlen 64 scopeid 0x1
    inet6 fe80::7c9:1eff:fe7e:ddc6%ap1 prefixlen 64 scopeid 0xe
    inet6 fe80::f7:b2e04fe9:5179%en0 prefxlen 64 secured scopeid 0xf
    inet 10.20.80.135 netmask 0xfffff00 broadcast 10.203.95.255
    
  • grep -v 127.0.0.1 用于排除 "127.0.0.1" 这个回环地址,因为这是本地回环接口的地址,不是真正的网络接口。

    "127.0.0.1" 是一个特殊的IP地址,通常称为 "回环地址" 或 "本地主机"。回环地址是IPv4地址范围中的一部分,它的主要作用是用于本地主机上的自测和通信。

    当计算机上的应用程序尝试连接到 "127.0.0.1" 时,它实际上是在尝试与自己进行通信。这种通信通常用于测试和开发目的,不需要实际的网络连接。

  • grep -v inet6 用于排除 IPv6 地址,只保留 IPv4 地址。

  • awk '{print $2}':使用 awk 工具来提取每行的第二个字段,这通常是 IP 地址部分。例如: ifconfig | grep inet | grep -v 127.0.0.1 | grep -v inet6 如果输出为:

    inet 10.203.80.135 netmask 0xfffff000 broadcast 10.203.95.255

    使用 awk 提取第二个字段即为 10.203.80.135

相关扩展:grep 工具

grep是一个文本搜索工具,它可以在文本文件中搜索与指定模式匹配的行。它是“全局正则表达式打印”(Global Regular Expression Print)的缩写。

基本语法:

grep [选项] 搜索模式 [文件名]
  • 选项grep 支持多种选项,用于控制搜索的行为。
  • 搜索模式:是你要查找的文本字符串,可以是普通文本或正则表达式。
  • 文件名:是你要搜索的文件名。如果不提供文件名,grep 将从标准输入(通常是键盘输入)读取文本。

选项概览

以下是一些常用的 grep 选项:

  • -ii 代表 "ignore case",表示不区分大小写搜索。
  • -vv 代表 "invert match",表示反转匹配,只显示不匹配的行。
  • -ll 代表 "files with matches",表示只显示包含匹配项的文件名,而不是匹配的行。
  • -cc 代表 "count",表示只计数匹配的行数,而不显示匹配的行。
  • -rr 代表 "recursive",表示递归搜索,用于搜索目录及其子目录中的文件。
  • -EE 代表 "extended regex",表示启用扩展正则表达式(支持更多正则表达式语法)。
  • -AA 代表 "after context",表示显示匹配行及其后的几行。
  • -BB 代表 "before context",表示显示匹配行及其前的几行。
  • -nn 代表 "line number",表示显示匹配的行及其行号。
  • -oo 代表 "only matching",表示仅显示匹配的文本,而不是整行。

常见用法示例:

使用 -i 选项进行不区分大小写搜索行

假设有一个文本文件 example.txt 包含以下内容:

Apple
Banana
apple
banana

要在不区分大小写的情况下搜索 "apple",可以使用 -i 选项:

grep -i "apple" example.txt

输出:

Apple
apple

使用 -v 选项反转匹配,搜索不匹配的行

假设有一个文本文件 fruits.txt 包含以下内容:

Apple
Banana
Cherry

要查找不包含 "Banana" 的行,可以使用 -v 选项:

grep -v "Banana" fruits.txt

输出:

Apple
Cherry

使用 -l 选项搜索包含匹配项的文件名

grep -l "404" *.log #只显示包含404的日志文件

grep -l "Pattern" file1.txt file2.txt #搜索多个文件

还可以搜索一个目录,举例来说,假设有一个名为 mydir 的目录,它包含以下结构:

mydir/
    file1.txt
    file2.txt
    subdir/
        file3.txt
        file4.txt

如果要在 mydir 目录及其子目录中搜索包含 "pattern" 的文件并显示文件名,可以使用以下命令:

grep -rl "pattern" mydir

输出将是:

mydir/file1.txt
mydir/subdir/file3.txt

这将返回所有包含 "pattern" 的文件的路径列表,包括它们的相对路径。

使用 -r 选项递归搜索目录,返回匹配行

假设有一个目录 mydir 包含多个文本文件,我们想要递归搜索整个目录及其子目录中的 "pattern"。

grep -r "pattern" mydir

这将搜索 mydir 目录及其子目录中的所有文件,查找包含 "pattern" 的行。

加上 -l 则返回匹配的文件名,加上 -n 则返回行号。

使用--include指定范围

grep -rl "apple" src/ --include="*.tsx"

使用 -n 选项显示匹配的行及其行号

假设有一个文本文件 example.txt 包含以下内容:

Line 1
This is Line 2
Line 3
Another Line 3

要显示包含 "Line 3" 的行及其行号,可以使用 -n 选项:

grep -n "Line 3" example.txt

输出:

3:Line 3
4:Another Line 3

使用 -c 选项计算匹配的行数

假设有一个文本文件 example.txt 包含以下内容:

Apple
Banana
apple
banana

要计算包含 "apple" 的行数,可以使用 -c 选项:

grep -c "apple" example.txt

输出:

2

使用 -E 选项启用扩展正则表达式搜索行

假设我们有一个文本文件 example.txt 包含以下内容:

apple
apples
applies

要查找包含 "apples" 或 "applies" 的行,可以使用 -E 选项启用扩展正则表达式:

grep -E "apples|applies" example.txt

输出:

apples
applies

使用 -A-B 选项搜索匹配行及其前后的几行

假设有一个文本文件 example.txt 包含以下内容:

Line 1
Line 2
Match: Line 3
Line 4
Line 5

要显示包含 "Match: Line 3" 的行及其前后的两行,可以使用 -A-B 选项:

grep -A 2 -B 2 "Match: Line 3" example.txt

输出:

Line 1
Line 2
Match: Line 3
Line 4
Line 5

使用 -o 选项仅显示匹配的文本,而不是整行

假设有一个文本文件 example.txt 包含以下内容:

apple:fruit
banana:fruit
cherry:fruit

要仅显示匹配 "banana" 的文本,可以使用 -o 选项:

grep -o "banana" example.txt

输出:

banana

使用 -z 选项设置null作为终止符

将 null 设置为终止符后,grep 在数据中查找匹配项不会被换行符等特殊字符终端中断。

例如你要匹配的文本中有换行时,需要把终止符设置为null,遇到换行时才不会被中断,从而被匹配

假设要匹配换行的中括号
{
  ...
};
# 不使用 -z,逐行匹配,默认情况下无法匹配多行文本块
grep -rlE '{[^}]*};' test --include="*.tsx"

# 使用 -z,可以匹配包含换行的多行文本块
grep -rlzE '{[^}]*};' test --include="*.tsx"

grep 遇到空格、制表符、换行符或其他特殊字符时,它会根据这些字符将文本划分为多行,然后逐行匹配模式。这是 grep 在文本中查找匹配项的默认行为。

所以你可以理解为使用 -z 后只有在这些特殊字符就可以正常匹配了,遇到了也不会划分新行。

使用 GNU grep

如果你执行完没效果,可能是因为你使用的 BSD grep,BSD grep对多行匹配以及复杂正则的支持不太好,安装下 GNU grep 就可以了:

brew install grep

这会在/usr/local/bin下安装ggrep。apple 芯片如 m2,可能会安装在/opt/homebrew/bin/ggrep,如果你找不到可以 which ggrep

然后设置 alias grep='/opt/homebrew/bin/ggrep',把grep命令链接到ggrep上,就可以正常使用了。

可以使用 grep --version 查看效果。

grep 非常强大,你可以根据具体的需求组合不同的选项和参数(指定文件名、文件扩展名、目录、多个文件等)来定制你的搜索。

相关扩展:awk 工具

awk 是一种用于文本处理的工具和编程语言,它可以在命令行环境下用于对文本文件进行各种操作,包括提取、转换、格式化和分析数据,awk 既是工具,也是一种编程语言。

具体来说:

  • 工具: awk 是一个命令行工具,你可以通过在命令行输入 awk 命令来处理文本数据。
  • 编程语言: awk 还是一种编程语言,它具有变量、条件语句、循环、函数等编程元素,可以编写复杂的脚本来处理文本数据。

在命令行中使用 awk 工具:

awk 'pattern { action }' file.txt

其中,pattern 是一个条件,当满足条件时,执行 action 中指定的操作。你可以在 action 中使用 awk 的编程语言特性来处理文本数据。

具体使用示例:

打印文本文件的某一列

awk '{print $1}' file.txt

打印 file.txt 文件的每一行的第一列。

根据条件过滤并打印行

awk '$3 > 50 {print $1, $3}' data.txt

data.txt 文件中筛选出第三列大于 50 的行,并打印出第一列和第三列的内容。

使用自定义分隔符

awk -F':' '{print $1, $3}' data.txt

: 作为分隔符,打印 data.txt 文件中的第一列和第三列。

使用条件语句

awk '{if ($2 > 50) print $1, "passed"; else print $1, "failed"}' scores.txt

根据第二列的分数判断学生是否通过,并相应地输出结果。

计算总和、平均值等

awk '{sum+=$3} END {print "Total:", sum, "Average:", sum/NR}' grades.txt

计算 grades.txt 文件中第三列的总和和平均值,并在文件末尾输出结果。

NR 是 "Number of Records" 的缩写,表示处理过程中已读取的记录(行)数量。它是一个内置变量,用于跟踪当前处理的行数。

在特定条件下修改数据

awk '{if ($3 > 90) $4="A"; else if ($3 > 80) $4="B"; else $4="C"}1' marks.txt

根据第三列的分数,在第四列中分配对应的等级。

查询域名 ip 地址

dig +short baidu.com A
  • dig:dig命令用于执行 DNS 查询操作。
  • +shortdig 命令的参数,它的作用是让 dig 命令输出更简洁,只显示查询结果的结果值,而不显示详细的查询信息。在查询结果中,仅输出记录的数据部分。
  • gnodetest.koolearn.com:这是要查询的域名。
  • A:这是查询的 DNS 记录类型,其中 A 记录用于将域名解析为 IPv4 地址。

相关扩展: dig 工具

dig(Domain Information Groper)是一个用于查询 DNS 信息的命令行工具。通常用于查找域名的 DNS 记录、解析 IP 地址、查询域名服务器等操作。

以下是一些常见的用法示例:

查询域名的 A 记录(IP 地址记录):

dig example.com

查询特定类型的 DNS 记录:

dig example.com MX       # 查询 MX 记录
dig example.com TXT      # 查询 TXT 记录
dig example.com NS       # 查询 NS 记录

查询指定 DNS 服务器的记录:

dig example.com @8.8.8.8   # 查询 example.com 在 Google DNS 上的记录

反向 DNS 查找(将 IP 地址解析为域名):

dig -x 8.8.8.8

显示详细的查询信息:

dig +trace example.com    # 显示 DNS 查询的详细跟踪信息

相反 +short 可以显示更简洁的信息

查询特定类型的 DNS 记录,并输出为 JSON 格式:

dig example.com MX +json

升级 bash

  1. 安装新版本的 Bash

    首先,通过 Homebrew 安装新版本的 Bash。执行以下命令:

    brew install bash
    
  2. 将新版本的 Bash 添加到可用的 Shell 列表中

    安装完成后,使用以下命令将新版本的 Bash 添加到可用的 Shell 列表中:

    sudo bash -c "echo /usr/local/bin/bash >> /etc/shells"
    

    把新版本的 Bash 路径添加到 /etc/shells 文件中,使其成为系统可识别的 Shell。

  3. 更改默认 Shell

    将默认 Shell 更改为新安装的 Bash

    chsh -s /usr/local/bin/bash
    

    这将将默认 Shell 更改为新版本的 Bash。

  4. 重启终端

    退出当前终端窗口并重新打开一个新的终端窗口,以使更改生效。

  5. 验证 Bash 版本

    在新打开的终端窗口中,运行以下命令来验证 Bash 的版本:

    bash --version
    

    推荐直接使用 zsh,比 bash 更强大,终端推荐 warp ,是一款集成AI的终端。

查看机器信息

查看当前Linux服务器的信息,包括 Linux 版本等,使用以下命令:

查看 Linux 版本和发行版信息:

cat /etc/os-release

或者

lsb_release -a

结果示例

NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

查看内核版本:

uname -r

# 打印全部系统信息
uname -a

查看服务器硬件信息(CPU、内存等):

lshw

查看服务器 CPU 信息:

cat /proc/cpuinfo

查看服务器内存信息:

cat /proc/meminfo

查看磁盘空间和分区信息:

df -h
  1. 查看网络接口信息:
ifconfig -a

查看服务器启动时间和运行时间:

uptime

要查看服务器的 CPU 核心数:

输出有关 CPU 的详细信息,包括核心数、线程数等。

lscpu

使用 nproc 命令:

nproc

这个命令将直接输出 CPU 的核心数。

使用 cat /proc/cpuinfo 命令:

cat /proc/cpuinfo | grep processor | wc -l

这个命令将输出 CPU 信息,然后通过 grepwc 命令来计算核心数。

wc -l 是一个用于统计行数的命令。wc 命令用于计算文件或输入中的行数、字数和字节数。

  • -l 选项表示只统计行数。

所以,当你在命令行中使用 wc -l 时,它会计算 /proc/cpuinfo 文件中的处理器行数,从而得出 CPU 核心数。

相关扩展: wc(word count) 命令

wc 是 "word count"(词汇统计)的缩写。虽然它的名称是 "word count",但它实际上可以用于统计文件或输入中的行数、字数和字节数,而不仅限于词汇。

  • 统计文件的行数wc -l file.txt
  • 统计文件的字数wc -w file.txt
  • 统计文件的字节数wc -c file.txt
  • 统计文件的最长行的长度wc -L file.txt

如果你不指定任何选项,那么 wc 命令将输出三个统计结果:行数、字数和字节数:

wc file.txt

你也可以同时指定多个选项,例如 wc -lw file.txt 会同时输出行数和字数。

vim 编辑器快捷键

Vim 是一个强大的文本编辑器,掌握下面这些快捷键和命令可以让你更高效地进行文本编辑,熟练了之后真的超级好用。以下是一些常用的 Vim 快捷操作:

vim 快捷键与我们计算机系统的快捷键是不一样的,例如撤销操作,我们首先想到的是 ctrl+z,vim是 u 键,大家首先要了解这一点才方便更好滴学习。

基本移动和编辑命令:

  1. 移动光标:

    • h - 左移
    • j - 下移
    • k - 上移
    • l - 右移
  2. 跳转:

    • w - 向前跳一个单词
    • b - 向后跳一个单词
    • 0 - 行首
    • $ - 行尾
    • gg - 文档开头
    • G - 文档末尾
  3. 复制、剪切和粘贴:

    • yy - 复制当前行
    • dd - 剪切当前行
    • p - 粘贴
  4. 撤销和重做:

    • u - 撤销
    • Ctrl + r - 重做
  5. 查找和替换:

    • /pattern:向前搜索指定模式。
    • ?pattern:向后搜索指定模式。
    • n:跳转到下一个搜索结果。
    • N:跳转到上一个搜索结果。
    • :s/old/new/g - 替换单行所有匹配的字符串
    • :%s/old/new/g:全局替换 oldnew

模式和编辑命令:

  1. 插入模式:

    • i - 在光标前插入
    • I - 在行首插入
    • a - 在光标后插入
    • A - 在行尾插入
    • o - 在当前行下插入新行
    • O - 在当前行上插入新行
  2. 可视模式:

    可视模式允许用户选择文本块以进行操作。在可视模式下,你可以使用键盘来选择文本,然后对所选择的文本执行各种操作,如复制、剪切、替换等。

    • v - 字符可视模式
    • V - 行可视模式
    • Ctrl + v - 块可视模式
  3. 命令模式:

    • : - 进入命令模式,可以执行命令(例如保存、退出等)

文件操作:

  1. :w - 保存文件
  2. :q - 退出 Vim
  3. :q! - 强制退出 Vim,不保存修改
  4. :wq - 保存并退出

窗口分割:

  1. :sp - 横向分割窗口
  2. :vsp - 纵向分割窗口
  3. Ctrl + w 后跟方向键 - 在窗口之间切换

多文件操作:

  1. :e filename - 打开新文件
  2. :bnext - 切换到下一个缓冲区文件
  3. :bprev - 切换到上一个缓冲区文件

自动补全:

  1. Ctrl + n - 向下补全
  2. Ctrl + p - 向上补全

标记和跳转:

  1. m + 字母 - 创建标记
  2. ' + 字母 - 跳转到标记
  3. ` + 字母 - 跳转回上一个位置

宏录制和重放:

  1. q + 字母 - 开始录制宏
  2. q - 停止录制宏
  3. @ + 字母 - 重放宏

折叠和展开:

  1. zf + 移动命令 - 创建折叠
  2. zo - 展开折叠
  3. zc - 折叠
  4. zR - 展开所有折叠

未尽事项,可以使用 :help 命令在 Vim 中访问内置的帮助文档。

如何在脚本内获取终端执行命令的目录

使用 pwd 命令:

在终端中直接运行 pwd 命令可以获取当前工作目录。

pwd

使用 dirs 命令:

dirs 命令会列出当前终端会话中的目录堆栈,第一行就是当前目录。

dirs -l -p | head -n 1
  1. dirs: 这是一个用于管理目录堆栈的内置命令。当你在终端中切换目录时,Bash 会将这些目录添加到堆栈中。

    前端的小伙伴目录堆栈可以理解为前端的路由

  2. -l: 表示输出完整的目录路径。如果不使用 -l 选项,将只输出目录的名称而不包括路径。
  3. -p: 表示输出的目录路径将包括所有的路径组成部分,而不是使用简化的路径。
  4. |: 管道操作符,用于将一个命令的输出作为另一个命令的输入。
  5. head -n 1: head 命令用于显示文本文件的前几行,默认显示前 10 行。 -n 1 选项表示只显示第一行。

dirs -l -p | head -n 1 的意思是:

  • 通过 dirs 命令获取目录堆栈中的所有目录路径,使用完整路径,不进行路径简化。
  • 将获取的目录路径通过管道传递给 head 命令,只显示第一行,即当前目录。

获取当前被执行脚本的所在目录

使用 dirname 命令和 $0 变量:

script_dir=$(dirname "$0")
echo "脚本所在目录:$script_dir"
  • $0:这个特殊变量在 Bash 脚本中表示当前脚本的名称,包括路径。例如,如果脚本的完整路径是 /home/user/myscript.sh,那么$0 将包含这个完整路径。
  • dirname:用于获取一个路径的目录部分,即去掉路径中的文件名部分。例如,dirname /home/user/myscript.sh 将返回 /home/user
  • script_dir=$(dirname "$0"):这行代码将获取当前脚本的完整路径(包括文件名),然后使用 dirname 命令提取出其中的目录部分,最终将这个目录路径存储在 script_dir 变量中。

获取当前git仓库名称(从文件路径中提取文件名)

如果你有多个项目,需要将它们遍历处理进行处理,例如将它们推送到不同的新仓库,你需要获取每个本地仓库的仓库名称,以推送到远程的新仓库

在脚本中使用以下命令即可

# 获取当前仓库名称
repo_url=$(git config --get remote.origin.url)
repo_name=$(basename $repo_url .git)

repo_url=$(git config --get remote.origin.url)

这一行命令使用 git config 命令获取当前 Git 仓库的远程 origin 的 URL,并将其存储在变量 repo_url 中。remote.origin.url 是 Git 配置中用于存储远程仓库 URL 的键名。--get 标志用于获取配置值。

repo_name=$(basename $repo_url .git)

这一行命令使用 basename 命令从 repo_url 中提取仓库名称,并去掉了 .git 后缀。提取后的仓库名称存储在变量 repo_name 中。

相关扩展 basename

basename 是一个命令行工具,用于从文件路径中提取文件名部分。它的作用是获取一个文件的基本名称,通常用于从文件路径中获取文件名,而不包括路径或文件扩展名。

关于工具和命令的区别:命令是 shell 内置的如lscdmkdir,工具是独立的可被shell集成的程序如grepsedawk

基本的用法是:

basename [路径] [后缀]
  • 路径:要提取文件名的路径字符串。
  • 后缀:可选参数,如果提供,将会去除文件名中的后缀。

以下是一些示例:

  1. 基本用法

    basename /path/to/file.txt
    

    输出:file.txt

    这会返回文件路径 /path/to/file.txt 中的文件名 file.txt

  2. 去除后缀

    basename /path/to/file.txt .txt
    

    输出:file

    basename 去除了文件名中的 .txt 后缀,返回了 file

文件/文件内容处理

批量修改文件名

修改 src 目录下的所有 index.scss 文件为 index.module.scss

#index.scss文件改为index.module.scss
find src -type f -name "index.scss" -exec sh -c 'mv "$0" "$(dirname "$0")/index.module.scss"' {} \;
  1. find src:脚本将在这个目录下搜索文件。

  2. -type f:表示要查找的是文件而不是目录。

  3. -name "index.scss":指定查找的文件名,即"index.scss"。

  4. -exec sh -c 'mv "$0" "index.module.scss"' {} +-exec选项指定在find找到的每个文件上执行的命令。

    • sh -c:这部分表示要执行一个shell命令,sh -c 指定执行单个命令字符串,而不必将它写入脚本文件或交互式输入。
    • 'mv "$0" "index.module.scss"':。使用mv命令来重命名文件,将文件从原来的"index.scss"重命名为"index.module.scss"。
    • {}:这是一个占位符,将被替换为find找到的每个文件的名称。
    • \:表示执行多次命令,每次一个文件作为参数。还有另外一个选项,+,使用 + 时,find 将多个匹配的文件合并到一起,会将多个匹配的文件一次性传递给 -exec 后面的命令,以提高效率和性能,但是不区分它们所在的目录,可能导致处理重名文件时产生问题,在多个目录可能存在重名文件时不要使用 +。

给所有文件名添加 -test 后缀

find src -name "*.ts" -exec sh -c 'mv "$0" "${0%.ts}-test.ts"' {} \;
  1. find ./src -name "*.ts":在src目录下查找所有的.ts文件。

  2. -exec sh -c '...' {} \;:对每个找到的文件执行shell命令。{}是一个占位符,代表找到的文件。

  3. 'mv "$0" "-test.ts"':使用mv命令将原文件名("0")重命名为新文件名(0")重命名为新文件名({0%.ts}-test.ts")。这里的{0%.ts}是一个字符串操作语法,它会将参数0(即原文件名)中的.ts删除,然后添加上-test.ts。

  4. ${0%.scss}: % 表示通配符,它在字符串操作中用于指示删除字符串中从 % 右边开始匹配的指定后缀,即 .scss

直接替换old_为new_

find test -type f -name "old_*.txt" -exec sh -c 'mv "$0" "${0/old_/new_}"' {} +

${0}:代表命令中的第一个参数,即当前文件的路径。

  • /old_/new_:这是替换操作。它表示将字符串 ${0} 中的第一个匹配到的 "old_" 替换为 "new_"。

所以 ${0/old_/new_} 的作用是将文件名中的 "old_" 替换为 "new_",还有其他字符串操作方法,后面再说。

批量修改文件内容

修改导入文件路径

将文件中引入index.scss改为index.module.scss

grep -rl "import './index.scss'" src/ --include="*.tsx" | xargs sed -i '' "s/import '\.\/index.scss'/import '\.\/index.module.scss'/g"

  1. grep -rl "import './index.scss'" src/ --include="*.tsx":使用grep命令在指定目录src/下查找包含字符串 "import './index.scss'" 的行。具体含义如下:

    • -r:递归地搜索指定目录下的文件。
    • -l:只显示包含匹配文本的文件名,而不显示匹配的具体文本内容。
    • --include="*.tsx":只搜索扩展名为".tsx"的文件。
    • "import './index.scss'":要搜索的字符串。
    • src/:要搜索的目录。
  2. |:管道操作符,将grep的输出传递给下一个命令。

  3. xargs sed -i '' "s/import '\.\/index.scss'/import '\.\/index.module.scss'/g":使用xargs命令接收grep的输出(即匹配的文件列表),然后使用sed命令在这些文件中执行替换操作。

    • xargs:从标准输入接受参数,按照定界符拆分并遍历参数,将其传递给后续命令,以执行命令批量操作。
    • sed -i '' "s/import '\.\/index.scss'/import '\.\/index.module.scss'/g":sed命令用于修改文本内容,这里执行替换操作。
      • -i '':表示直接在原始文件上进行替换,并且在进行替换之前将原文件备份为一个空文件(mac下需设置,linux不需要)。
      • "s/import '\.\/index.scss'/import '\.\/index.module.scss'/g":这是sed的替换表达式,s/表示执行替换操作,用于查找 "import './index.scss'" 并将其替换为 "import './index.module.scss'"。g 表示全局替换,而不仅仅替换第一个匹配项。
      • 当从标准输入读取数据时,不需要为sed命令指定文件名,因为会默认传入

修改标签类名

修改src目录下所有tsx文件中的className='index'为className='目录名-index'

如文件为 src/pages/coupon/index.tsx 的话 className则改为className='coupon-index'

# 使用 grep -rl + xargs
grep -rl "className='index'" src --include="*.tsx" | xargs -I {} sh -c 'sed -i "" "s/className='\''index'\''/className='\''$(basename $(dirname {}))-index'\''/g" {}'

| xargs -I {} sh -c 'sed -i "" "s/className='\''index'\''/className='\''$(basename $(dirname {}))-index'\''/g" {}':这一部分将 grep 命令的输出传递给 xargs,并使用 xargs 执行一个内联的 shell 命令,该 shell 命令使用 sed 来进行替换操作。具体解释如下:

  • xargs:从标准输入接受参数,按照定界符拆分并遍历参数,将其传递给后续命令,以执行命令批量操作。

  • -I {}:-I 选项指定占位符,这部分告诉 xargs 将每个输入的行(文件名)替换为 {},以便在后续命令中使用。

  • sh -c 'sed -i "" "s/className='\''index'\''/className='\''$(basename $(dirname {}))-index'\''/g" {}':这是一个内联的 shell 命令,如果命令包含需要在 shell 中解释的复杂脚本、变量替换等,需要使用 sh -c在 shell 环境中执行。

    • sed -i "" "s/className='\''index'\''/className='\''$(basename $(dirname {}))-index'\''/g" {}

      • -i "":告诉 sed 在原始文件上进行编辑,而不是输出到标准输出。这个选项后面的 "" 表示在执行替换操作时不创建备份文件。

      • "s/className='\''index'\''/className='\''$(basename $(dirname {}))-index'\''/g"

        • s/sed 的替换操作符。
        • className='\''index'\'':这是要查找并替换的文本,其中单引号 '\'' 用于将单引号嵌套在单引号字符串中,与单引号包裹的内容组合,第一个引号为结束前面的字符串,倒数第一个引号为开始后面的字符串。\'是转义序列中的单引号,相当于把整个字符串分开,然后在中间加入 \',还有其他转义序列,后面说。
        • $(basename $(dirname {}): 表示获取文件所在的目录名,例如 src/a/index.tsx 文件,basename 命令会获取到 a
        • g:表示替换所有匹配项,而不仅仅是第一个匹配项。

以上命令如果文件名过长,整个命令组合后的长度会超出限制,执行时会出现 xargs: command line cannot be assembled, too long,遇到这种情况我们可以换种写法:

# 使用 find -exec
find src -name "*.tsx" -exec grep -l "className='index'" {} \; -exec sh -c 'sed -i "" "s/className='\''index'\''/className='\''$(basename $(dirname {}))-index'\''/g" {}' \;

# 使用 grep -rl + while
grep -rl "className='index'" src --include="*.tsx" | while read file; do sed -i "" "s/className='index'/className='$(basename $(dirname $file))-index'/g" "$file"; done

内容删除或提取

将文件中的配置部分提取到另一个文件

例如 taro2 升级到 taro3,文件内的配置都单独提取到config.js文件中了

/*
  其他代码
  ...
*/
config: Config = {
  title: '标题',
  ...
};

// 提取到 xx.config.ts
export default definePageConfig( {
  title: '标题',
  ...
});

使用以下命令可以快速做完这件事:

grep -rlzE '.*config.*=\s+{([^{}]*)};' test --include="*.tsx" | while read file; do
  config_file="${file%.*}.config.ts"
  config_content=$(grep -zoP '.*config.*=\s+{[^}]*}' "$file" | sed 's/.*=\s*//' | tr -d '\0')
  echo "export default definePageConfig($config_content);" > "$config_file"
  sed -iE '/.*config.*= {/,/};/d' $file
done
  1. grep -rlzE '.*config.*=\s+{([^{}]*)};' src --include="*.tsx":使用 grep 搜索包含匹配文本的文件:

    • -r:递归搜索目录。
    • -l:只显示包含匹配文本的文件名。
    • -z:使用 null 字符('\0')作为文件名分隔符,因为要进行多行匹配所以要换个分隔符。
    • -E:启用扩展正则表达式。
    • '.*config.*=\s+{([^{}]*)};':它匹配包含 "config" 的文本行,后面跟等号和配置对象内容。
  2. | while read file; do:将 grep 命令的输出传递给一个 while 循环,每次迭代处理一个匹配的文件。

  3. config_file="${file%.*}.config.ts":用于生成要写入的配置文件的文件名。这里的{file%.*}是一个字符串操作语法,它会将参数0(即原文件名)中的扩展名删除,然后换成.config.ts。例如,a.tsx转换为 a.config.ts 格式。

  4. config_content=$(grep -zoP '\w*\.?config:?\s*\w*\s*=\s+{[^}]*}' "$file" | sed 's/.*=\s*//' | tr -d '\0'):这部分用于提取配置对象的内容,并将其保存到 config_content 变量中。

    • grep -zoP '\w*\.?config:?\s*\w*\s*=\s+{[^}]*}' "$file":它查找匹配配置对象的文本,-o 表示只返回匹配的内容不返回整行,整行可能还包含分号等,这里不需要,-P 表示使用 perl 兼容的正则表达式,提供了更多高级的模式匹配功能,包括 \s 特殊字符等。
    • sed 's/.*=\s*//':使用 sed 删除匹配行中等号及其前面的内容,只保留配置对象的内容。(与/d的区别是/d会删除行,而 // 形式只会删除内容,行会保留)
    • tr -d '\0':用于删除结尾的 null 字符。
  5. echo "export default definePageConfig($config_content);" > "$config_file":用于将提取的配置内容写入 .config.ts 文件。重复执行会覆盖。

  6. sed -iE '/.*config.*= {/,/};/d' $file:用于在原文件中删除配置对象的内容。具体解释如下:

    • sed -iE '/.*config.*= {/,/};/d' $file:正则表达式 /.*config.*= {/,/};/ 匹配配置对象的起始行和结束行之间的所有内容,起始行和结束行以逗号分隔,然后 d 命令删除这些行。

批量删除文件

快速删除src目录下所有扩展名为bak的文件

find src -type f -name "*.bak" -exec rm {} \;
find src -type f -name "*.bak" -print0 | xargs -0 rm -f;
  1. -print0: find 命令的输出是一个以换行符、空格、制表符等特殊字符终止的文件名列表,如果文件名本身包含空格或其他特殊字符,这会导致文件名被错误地解释为多个文件名。 使用-print0则表示文件名以null(\0)分隔,而不是以换行符(\n)等特殊字符分隔。

  2. xargs -0: 指定xargs使用 null 作为定界符。确保在处理包含空格或特殊字符的文件名时,命令能够正确运行。

  3. rm -f: 表示强制删除,即使受保护或只读属性限制

-print0 和 xargs -0 的组合是为了确保处理包含特殊字符或空格等的文件名时不会出现问题。

相关扩展: find 工具

find 是一个用于查找文件和目录的命令行工具。find 命令的基本语法如下:

find 起始目录 [匹配条件] [动作]
  • 起始目录:指定开始搜索的目录。

  • 匹配条件:可选,用于指定搜索的匹配条件,如文件名、类型、大小、权限等。这些条件可以通过 -name-type-size-perm 等参数来定义。

  • 动作:可选,用于指定在找到匹配文件时执行的操作,如打印文件名、执行命令等。常用的动作包括 -print-exec 等。

以下是一些示例说明:

查找指定文件名的文件:

find /path/to/search -name "example.txt"

/path/to/search 目录及其子目录中查找名为 "example.txt" 的文件。

查找指定文件类型的文件:

find /path/to/search -type f

查找 /path/to/search 目录及其子目录中的所有普通文件。

查找指定目录:

find /path/to/search -type d

查找 /path/to/search 目录及其子目录中的所有目录。

查找指定文件大小的文件:

find /path/to/search -size +1M

查找 /path/to/search 目录及其子目录中大小大于 1MB 的文件。

执行命令来处理匹配的文件:

find /path/to/search -name "*.log" -exec rm {} \;

查找 /path/to/search 目录及其子目录中所有以 ".log" 结尾的文件,并删除它们。

find 命令的 -exec 选项可以在找到匹配的文件时执行指定的命令。区别在于 -exec 后面的 ;+

  - `-exec` 后面使用 `\;`,这表示每次找到匹配的文件时都会执行一次 `rm` 命令,对于每个匹配的文件,`find` 将执行一次 `rm` 命令。

  - `-exec` 后面使用 `+`,这表示 `find` 将尝试将多个匹配的文件传递给单个 `rm` 命令, `find` 会收集所有匹配的文件,然后将它们作为参数传递给一个 `rm` 命令。这样更高效,它减少了每次执行命令的开销。

相关扩展: sed 工具

sed 是一种流编辑器(stream editor),用于文本处理和转换。它在文本流中执行替换、删除、插入等编辑操作,通常与管道一起使用。

基本语法:

sed [选项] '编辑命令' 文件名
  • [选项]sed 可以使用不同的选项来修改其行为,如 -i 用于原地编辑文件。
  • '编辑命令':指定要执行的编辑操作的一组命令。
  • 文件名:要处理的文件名。

示例说明:

替换文本:

使用 sed s/ 可以轻松替换文本。例如,要将文件中的所有 "apple" 替换为 "banana":

sed 's/apple/banana/' filename.txt

原地编辑文件:

如果要在原始文件上执行替换操作,可以使用 -i 选项。例如,将所有 "apple" 替换为 "banana" 并在原始文件上保存更改:

sed -i 's/apple/banana/' filename.txt
# mac
sed -i '' 's/apple/banana/' filename.txt

删除行:

删除包含 "unwanted" 的所有行:

sed '/unwanted/d' filename.txt

插入文本:

sed 可以在匹配到的行前或后插入文本。例如,在每一行前插入 "Prefix: ":

sed -i '' 's/^/Prefix: /' filename.txt

多个编辑操作:

将文件中所有 "apple" 替换为 "banana" 并在每行前添加 "Item: ":

sed -e 's/apple/banana/' -e 's/^/Item: /' filename.txt

正则表达式匹配

sed 支持使用正则表达式进行更复杂的文本匹配和替换。例如,将所有以数字开头的行替换为 "Number: ":

sed 's/^[0-9]\+/Number: /' filename.txt

反向引用

sed 支持创建捕获组并引用,使用( 和 ) 来创建捕获组

echo "This is some text with parentheses." | sed 's/.*\(some text\).*/\1/'
echo "This is some text with parentheses." | sed -r 's/.*(some text).*/\1/'

启用扩展正则表达式

使用 -r 启用扩展的正则表达式,可以使用更多的元字符和语法来编写你的正则表达式。

默认情况下,sed 使用基本正则表达式语法,其中特殊字符如 +、?、| 等不具备特殊含义,除非在它们前面加上反斜杠 \。使用 -r 选项,这些特殊字符可以直接使用,而不需要转义。

# 使用扩展正则表达式语法
echo "apple banana cherry" | sed -r 's/(apple|banana)/fruit/'

# 不使用扩展正则表达式语法,需要转义 |
echo "apple banana cherry" | sed 's/\(apple\|banana\)/fruit/'

多行处理

sed 可以处理多行文本。例如,删除包含 "start" 和 "end" 之间的文本:

sed '/start/,/end/d' filename.txt

执行多个编辑命令

您可以将多个编辑命令组合在一起以执行复杂的文本操作。例如,将 "apple" 替换为 "banana",并删除包含 "unwanted" 的行:

sed -e 's/apple/banana/' -e '/unwanted/d' filename.txt

相关扩展: xargs 工具

xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。

xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。

xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。

xargs 默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代

之所以能用到这个命令,是由于很多命令不支持 | 管道来传递参数,而日常工作中有这个必要,所以就有了 xargs 命令。

简单点说就是 xargs 可以遍历参数

xargs 的基本语法如下:

command | xargs [options] command_to_run

其中:

  • command 是产生要传递给 xargs 的数据的命令。
  • [options] 是可选的 xargs 选项。
  • command_to_run 是要执行的命令,该命令将接受从 xargs 获取的参数。

以下是一些 xargs 的常用选项和示例说明:

格式化文本:以空格分隔

ls 命令的输出传递给 echo 命令以列出当前目录的文件,以空格分隔

ls | xargs

使用 -n 选项:指定每个 xargs 命令执行的参数数量

每次执行 xargs 命令时带的参数,默认为所有参数

ls | xargs -n 2

这将每次将两个文件名传递给 echo

使用 -I 选项:指定替代标记,在特定位置插入参数。

使用 -I 指定一个替换字符串 {},这个字符串在 xargs 扩展时会被替换掉,当 -I 与 xargs 结合使用,每一个参数命令都会被执行一次,即相当于 -n1

echo "file1 file2" | xargs -I {} mv {} /destination

{} 将替换为从 echo 中获取的文件名。

使用 -0 选项:处理带有空格或特殊字符的文件名。

find . -type f -print0 | xargs -0 rm

-print0-0 一起使用,以便处理文件名中包含空格或特殊字符的文件。

结合 find 命令:查找文件后进行操作

find /path/to/search -name "*.txt" | xargs grep "search_string"

这将查找指定路径下的所有 .txt 文件,并在其中搜索指定的字符串。

find test -type f -name "*.tsx" -print0 | xargs -0 wc -l

这将统计指定路径下的所有 .tsx 文件中的行数。

find . -type f -name "*.log" -print0 | xargs -0 rm -f

批量删除文件

批量下载链接

假如你有一个文件包含了很多你希望下载的 URL,可以使用 xargs下载所有链接:

cat url-list.txt | xargs wget -c

相关扩展: 转义序列 \n \t \r 等

转义序列是在编程和计算机科学领域中使用的特殊字符组合,用于表示一些不可见或特殊的字符以及控制字符。这些序列以反斜杠(\)字符开头,后面跟着一个或多个字符,形成一个编码,表示某种特殊含义。

转义序列通常用于字符串中,以告诉解释器或编译器如何处理这些字符。一些常见的转义序列包括:

  1. \':表示单引号。
  2. \":表示双引号。
  3. \\:表示反斜杠字符。
  4. \n:表示换行(换行符)。
  5. \t:表示水平制表符。
  6. \r:表示回车。
  7. \b:表示退格。
  8. \f:表示换页。
  9. \v:表示垂直制表符。
  10. \0:表示空字符或字符串终止符。
  11. \xHH:表示十六进制值,其中 HH 是两个十六进制数字。

转义序列使得在字符串中插入特殊字符成为可能,而不会与字符串的定界符或文本解释器产生冲突。例如,如果你想在一个包含双引号的字符串中插入一个双引号字符,你可以使用 \" 来表示它,以便编译器或解释器知道这个双引号是字符串的一部分,而不是字符串的终止符。

如何输出单引号

与单引号包裹的字符串进行拼接或嵌套

echo 'This is a single quote: '\'' in a single-quoted string.'
# This is a single quote: ' in a single-quoted string.

echo \''Hello, world!'\'
# 'Hello, world!'

echo \'hello\'
# 'hello'

总结

这篇文章旨在让大家能够快速查阅到自己想要的操作,文章会尽可能的全而详细地收录所有常用操作,并且会持续更新,与大家共勉,争取早日 shell 命令敲的飞起,节省下来的时间多和大家分享知识(手动狗头)~

感谢你花费宝贵的时间阅读本文,如果本文给了你一点点帮助或者启发,还请三连支持一下,点赞、关注、收藏,作者会持续与大家分享更多干货。