Shell 常用命令、基本用法总结
Filter
Filter 常用于从大量文本、数据中提取需求的部分。下面介绍几个常用的 filter 命令。
cut
$ cut -c 5-8 textfile.txt # 切出 textfile.txt 中每行的第 5 到第 8 个 character
$ cut -f2-4 -d',' textfile.txt # 切出 textfile.txt 中每行的第 2 到第 4 块 field,field 由 delimiter “,” 确定
$ cut -f2,4 -d'|' textfile.txt # 切出 textfile.txt 中每行的第 2 、第 4 块 field, field 由 delimiter “|” 确定
uniq
$ sort | uniq -c # aggregation (带 count),类似 SQL 中的 GROUPBY
egrep
$ egrep -o <pattern> textfile.txt # 只返回 match pattern 的部分
$ egrep -x <pattern> textfile.txt # 只有文件的某行 (line) fully match pattern 的时候才返回
$ egrep -w <pattern> textfile.txt # 只有文件的某字 (word) fully match pattern 的时候才返回
wc
$ wc -l textfile.txt # 返回行数计数
$ wc -m textfile.txt # 返回char计数
$ wc -w textfile.txt # 返回word计数
tr
$ tr <srcChars> <destChars> # 将输入字符中含有 srcChars 的字符对应替换成 destChars
$ tr 'a-z' 'A-Z' # 将输入字符的小写字母转为大写
$ tr -d ' ' # 删除输入字符中所有的空格
$ tr -cs 'a-zA-Z0-9' '\n' # 切出在 SET 'a-zA-Z0-9' 中的连续字符,并按行输出
sed
$ sed 's/regex/replacement/ig' # 将 match regex 的部分全部替换成 replacement
$ sed -E -n 's/regex-with-capture-group/\1/p' # 用regex的group capture提取子串
$ sed -E -n '/regex/p' # mimic grep -E 'regex'
cat
$ cat >new_textfile.txt<<eof # 新建并从 stdin 按行写入文件 new_textfile.txt,直到遇到 eof 结束
$ cat >>new_textfile.txt<<eof # 从 stdin 按行连接写入文件 new_textfile.txt,直到遇到 eof 结束
ps
$ ps -eo pid,user:20,cmd |grep $pid # 查询PID的用户名、命令
Shell Script 入门
介绍 Shell 的一些常识和基本用法。
准备工作
Shell 脚本文件头
#!/bin/bash # 告诉 Linux 该文件用 bash 运行
可执行模式
$ chmod +x shell_script.sh # 修改 shell_script.sh 为可执行文件
常用命令
SSH
远程连接服务器(以 AWS 为例)
如果要连接 AWS, 需要联系管理员拿到私钥文件(扩展名为 .pem)。
$ ssh -i "private-key.pem" user_name@domain_name
如果想在 AWS 上运行 jupyter,tensorboard 等任务,可以使用 local forwarding 功能,将本地操作转发到远端服务器:
$ ssh -i "private-key.pem" <local-port>:127.0.0.1:<remote-port> user_name@domain_name
ALIAS
给一些常用命令+参数设置别名
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
alias python3='python3.7'
alias scp='scp -o "StrictHostKeyChecking no" -o "UserKnownHostsFile /dev/null" -o "PasswordAuthentication yes"'
alias ssh='ssh -o "StrictHostKeyChecking no" -o "UserKnownHostsFile /dev/null" -o "PasswordAuthentication yes"'
sudo update-alternatives --install /usr/local/bin/python3 python3 /usr/local/bin/python3.11 1
STDIN
$ read a_str_variable # 从 stdin 读取字符串存入 a_str_variable 变量
$ read -t 3 a_str_variable # 3s 内无输入则退出(返回值 142)
$ read -s a_str_variable # 不显示输入字符,输入密码等机密信息时使用
$ read -p "Name? " # 相当于 Python 中的 input("Name? ")
$ read -r a_str_variable # 当输入的字符中含 “\” (反斜杠)时,保留 “\”。如果没有设置 -r,则反斜杠都会被 “吃掉”
# 参考:https://unix.stackexchange.com/questions/18886/why-is-while-ifs-read-used-so-often-instead-of-ifs-while-read/18936#18936
STDOUT
$ echo string
图片转换
$ convert original_image.png converted_image.jpg # 图片格式转换,支持格式:jpg, png, gif, bmp, tif
$ convert -gravity south \ # 设置 draw text 的位置
-pointsize 36 \ # 设置字体大小
-draw "text 0,10 'Hello world'" original_image.jpg converted.jpg
文件搜索
$ find # 递归输出当前目录及其下所有文件或子目录,相当于`find . -print`
$ find dir # 递归输出dir 目录及其下所有文件或子目录
$ find dir -type f # 递归输出dir 目录下的所有文件
$ find dir -type d # 递归输出dir 目录及其下的所有子目录
$ find dir -name '*s2_COMP9041' # 递归输出dir 目录下所有符合通配符 `*s2_COMP9041` 的文件名或目录名(*此处不匹配斜杠/)
$ find dir -iname '*s2_comp9041'# 递归输出dir 目录下所有符合通配符 `*s2_comp9041` 的文件名或目录名(*此处不匹配斜杠/)(case insensitive)
$ find dir -path '*.sh' # 递归输出dir 目录下所有符合通配符 `*.sh` 的文件路径或目录路径(*此处匹配斜杠/)
$ find dir -ipath '*.SH' # 递归输出dir 目录下所有符合通配符 `*.sh` 的文件路径或目录路径(*此处匹配斜杠/)(case insensitive)
$ find dir -path '*.sh' \ # <或>操作
-or -path '*.pl' \
-or -path '*.py'
$ find dir -not -name '*.sh' \ # <非>操作
-type f
$ find dir -path '*.tmp' \ # <与>操作
-type f -delete # 递归删除dir 目录下所有路径符合通配符 `*.tmp` 的文件
$ find dir -name '*s2_COMP9041'\# 递归遍历dir 目录下所有
-type d \ # 的目录名
-prune # 如果目录名符合通配符 `'*s2_COMP9041'`,该目录下所有内容都被忽略
-print # 并输出(该选项可省略)
$ find dir -name '*s2_COMP9041'\# 递归遍历dir 目录下所有
-type d \ # 的目录名
-prune # 如果目录名符合通配符 `'*s2_COMP9041'`,该目录下所有内容都被忽略
-or -print # 输出其它未被忽略的目录及文件
# 有时可能仅仅需要排除目录,而非连同该目录下的所有文件。此时需要用到 -depth 选项
$ find dir -depth \ # 规定遍历顺序:遇到目录时,先列出目录中的文件,再列出目录自己
-name '*s2_COMP9041'\# 递归遍历dir 目录下所有
-type d \ # 的目录名
-prune # 如果目录名符合通配符 `'*s2_COMP9041'`,该目录下所有内容都被忽略
-or -print # 输出其它未被忽略的目录及文件
# 参考:https://math2001.github.io/post/bashs-find-command/
条件判断
#!/bin/bash
# 参数个数检查
if test $# -ne 2
# 或 if [ $# -ne 2 ]
# 或 if (( $# != 2 ))
then
echo Usage: "$0": '<non-negtive_int> <string>'
exit 1
fi
# 参数类型检查
if test $1 -ge 0
# 或 if [ $1 -ge 0 ]
then
:
else
echo "$0": argument 1 must be a non-negtive integer!
exit 2
fi
# 程序逻辑开始...
for
Loop
# 遍历当前目录中的所有文件名
## Version 1 ## 不包括隐藏文件 ##
$ shopt -u dotglob
$ for filename in *
> do echo $filename
> done
## Version 2 ## 包括隐藏文件 ##
$ shopt -s dotglob
$ for filename in *
> do echo $filename
> done
## 根据 argument 输入的目录路径 `important_files/*` 遍历其中(包括子目录)所有的文件
# Input: $ readfile.sh important_files/*
$ for paths in "$@" # 注意! 1.不是$1 2.Add double quotes
> do
> find $paths -type f -print0 |
> while read -d $'\0' path
> do echo $path
> done
> done
# 类似 C语言 的用法
$ begin=0; end=5; step=1
$ for ((i=$begin; ((i < $end)); ((i += $step)) ))
> do echo $i
> done
# write files from arguments by line with line number
line_no=0
for word in "$@"
do
((line_no+=1))
echo $line_no $word
done > filepath
while
Loop
# 类似 C语言 的用法
$ begin=0; end=5; step=1
$ i=$begin
$ while test $i -lt $end <OR> while [ $i -lt $end ] <OR> while (( i < end ))
> do echo $i
> (( i+=step ))
> done
# read files by line
while read line
do
echo $line
done < filepath
sh
$ sh -x your_shell_script.sh # 用于追踪程序流,debug 时很实用
一些细节
Silence
$ egrep 'regex' filename.txt >/dev/null 2>&1 # >/dev/null —— stdout(1) 被扔到 /dev/null
# >2>&1 —— stderr(2) 跟着 stdout(1) 走
# 总结:不在屏幕上打印 stdout 和 stderr
引号问题,date
用法,图片处理
# 实际应用:给图片打tag
$ date_time=`date "+%H:%M %d %b,%Y"`
$ convert -draw "text 0,0 '$date_time'" oringal.jpg tagged.jpg
Linux 文件名相关问题
文件名以 “-” 开头
$ mv -- filename(以‘-’开头) newfilename # -- 表示下一个参数不会是 Option(必须是文件名)
文件名中绝对不能包含的字符
['/', '\0']
文件名大小写敏感
$ touch important_file.db Important_File.Db IMPORTANT_FILE.DB
$ ls
important_file.db Important_File.Db IMPORTANT_FILE.DB
分类:
Scripts
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)