Linux使用技巧

Docker

Docker is a tool to run Linux containers based on selected images.

Docker从入门到实践

https://yeasy.gitbook.io/docker_practice/

Win10家庭版用WSL2运行Docker Desktop,将数据从C盘迁移到其他目录

Win10开始使用Hyper-V运行docker,家庭版无此功能,所以只能pro版本才能用docker desktop。后来升级到2004系统后,家庭版可升级WSL(Windows Subsystem for Linux)至WSL2,便可基于WSL2运行docker desktop,但相较于Hyper-V的区别在于,其数据由WSL2代为管理,无法在docker里设置镜像存储路径。

安装docker后,docker会自动创建2个发行版:docker-desktopdocker-desktop-data,其默认安装在C盘,在%LOCALAPPDATA%/Docker/wsl目录里,而docker的运行数据、镜像文件都存在%LOCALAPPDATA%/Docker/wsl/data/ext4.vhdx中,比较占用C盘空间,故考虑将其迁移至D盘。

对于WSL发行版的迁移,网上教程基本均需使用LxRunOffline,但其虽然可以迁移例如Ubuntu的发行版,但迁移不了docker自动创建的2个发行版。故考虑如下两种方式:

方法一:使用wsl命令

  • 关闭docker desktop

  • 关闭所有发行版

  • 导出docker-desktop-data

  • 注销docker-desktop-data

  • 重新导入docker-desktop-data

  • 注:只迁移docker-desktop-data即可,另一个占用空间较小

方法二:修改注册表(未直接验证,理论上及其他操作证明应当可行)

  • 关闭docker desktop

  • 打开powershell,输入whoami /user,获得[SID];用wsl --shutdown命令关闭所有发行版

  • 运行regedit,跳转至HKEY_USERS\[SID]\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss

  • 在下属的文件文件夹中(文件夹名为一个UUID)找到DistributionNamedocker-desktop-data的项

  • 将其BasePath改为目标目录,如\\?\D:\Tools\WSL\docker-desktop-data,并将原目录下ext4.vhdx拷贝至该目录

  • 重启即可使用

Docker创建共享文件夹

  • 检查docker是否安装成功

  • 装载镜像

  • 创建共享文件夹

  • 创建容器(win10下共享文件夹需用绝对路径

  • 将docker中的/home/test/shareroot所有改为test所有

  • test用户运行docker

  • 注:以root用户运行docker

鳥哥的Linux私房菜

http://linux.vbird.org/linux_basic/

Linux常用命令

https://mp.weixin.qq.com/s/cri9CEbVJizZIO9WwiCJ0g

Linux特殊符号

https://mp.weixin.qq.com/s/IO8Ckahig14RIvyDPX5lhw

三十分钟学会AWK

https://github.com/mylxsw/growing-up/blob/master/doc/%E4%B8%89%E5%8D%81%E5%88%86%E9%92%9F%E5%AD%A6%E4%BC%9AAWK.md

三十分钟学会SED

https://github.com/mylxsw/growing-up/blob/master/doc/%E4%B8%89%E5%8D%81%E5%88%86%E9%92%9F%E5%AD%A6%E4%BC%9ASED.md

Learn Vim Progressively

http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/

Linux查看系统基本信息

  • 查看版本当前操作系统内核信息

  • 查看当前操作系统版本信息

  • 查看版本当前操作系统发行版信息

  • 查看cpu相关信息,包括型号、主频、内核信息等

  • 查看服务器名称

  • 查看网络信息

  • 查看磁盘信息

  • 查看进程与用户信息

Bash和Sh的区别

Bash is the most commonly used linux shell.

  • sh(或Shell命令语言)是由POSIX标准描述的一种编程语言。它有很多实现(ksh88, dash,…)。bash也可以被认为是sh的实现。因为sh是规范,不是实现,/bin/sh是在大部分POSIX系统上实际实现的符号连接(or 硬链接)。

  • bash是兼容sh的一种实现(虽然在几年之前被视为POSIX标准),但随着时间流逝,它需要更多的扩展。这里面的一些扩展会改变有效的POSIX shell脚本的行为,所以bash本身不是有效的POSIX shell,而是POSIX shell语言的方言。但bash可以执行--posix切换,使得它更加的兼容POSIX,同时也尝试通过调用sh来模仿POSIX。

  • 长期以来,在大部分GNU/Linux系统上,/bin/sh都是指向/bin/bash。结果,几乎可以忽略两者之间的区别了。但是这种情况最近开始改变。

  • /bin/sh不指向/bin/bash(在某些情况下甚至都不存在/bin/bash)的系统中,一些常见的例子是:

    • 现代的debian和ubuntu系统上,sh默认是dash的符号链接

    • Busybox,它通常在Linux系统引导时作为initramfs的一部分运行。它使用了ash shell实现。

    • BSDs,以及通常所有非linux系统。OpenBSD 使用pdksh,Korn shell的后代。FreeBSD的sh是原始UNIX Bourne shell的后代。Solaris有它自己的sh,但长期以来都不是与POSIX兼容的,是一种Heirloom项目提供的一个开源实现。

  • 如何找到/bin/sh在我们系统上的指向

    • /bin/sh的复杂之处是:它可以是符号链接也可以是硬链接。

    • 如果是符号链接,可以尝试:

    • 如果是硬链接,可以尝试:

    • 注:实际上-L标志同时包括符号链接和硬链接,但是这种方法的缺点是它不是可移植的,POSIX不需要find来支持-samefile选项,尽管GNU find和FreeBSD find都支持它。

  • Shebang:在计算领域中,Shebang(也称为Hashbang)是一个由井号和叹号构成的字符序列#!,其出现在文本文件的第一行的前两个字符。最终,通过在脚本的第一行编写Shebang来决定使用sh还是bash。

利用.bashrc个性化配制bash环境

示例一

示例二

利用.vimrc个性化配置vim

  • 复制一份vim配置模板到个人目录下

  • 利用vim编辑该文件

Bash下使用rsynccrontab备份文件

  • Install rsync and crontab

  • Prepare backup directory

  • Prepare a backup script, for example, ~/backup.sh

  • Using crontab command to execute the backup script routinely, and record in a log file, for example, execute the command ~/backup.sh > ~/backup.log in 5:10am everyday:

    • add executable permission

    • open crontab and edit it by the following command:

    • type in the following lines or write the following in a file (i.e. ~/crontab):

    • exit and save

Linux中for循环的几个常用写法

  • 数字型循环

  • 字符型循环

  • 路径查找型循环

Linux下将文件夹命名为今天的日期的方法

Linux下使ls命令只显示目录的方法

附:ls与cd连用示例

Linux下替换^M字符方法

在Linux下使用vicat -A查看一些在Windows下创建的文本文件,有时会发现在行尾有一些^M,是由于Linux的换行符为LF,而Windows的换行符为CRLF所造成。它的存在虽然不影响文件的一般查看,但会影响利用awkgrep等命令对文件进行操作,见下:

有如下解决方法:

  • 使用dos2unix命令(建议所有在win下创建的文件均先在root用户下运行此命令转换一下格式

  • 使用vi的替换功能,在vi的命令模式下输入:

  • 使用sed命令

  • 注:在vim的.vimrc文件中把fileformat=unix去掉便不会显示(默认不显示^M)

附:Windows下使用git时保证为LF格式

Linux下将多行文件合并为一行

  • 注意:对于win下文件(非linux创建),建议先运行dos2unix命令

  • 使用awk命令

  • 使用sed命令:sed默认按行处理,N可以让其读入下一行,再对\n进行替换,这样就可以将两行并做一行。但为了将所有行并作一行,需要采用其跳转功能。:flag在代码开始处设置一个标记flag,在代码执行到结尾处时利用跳转命令t flag重新跳转到标号flag处,重新执行代码,这样就可以递归将所有行合并成一行。

  • 使用xargs命令

  • 附:文件合并、行筛选、多行合并脚本示例

Linux中cut命令

  • cut是一个选取命令,其以行为单位,选择性输出符合条件的内容到标准输出,使用格式为:

  • 命令选项:

  • 使用示例

Ubuntu镜像使用帮助

  • Ubuntu的软件源配置文件是/etc/apt/sources.list。将系统自带的该文件做个备份,再将该文件替换为下面内容,即可使用TUNA的软件源镜像。

Ubuntu下使用apt install XX(or sudo apt install XX)报错Unable to locate package

  • 正常情况下,只需要更新软件列表

  • 当上述命令无效时,尝试升级

  • 注:一般情况下更改了软件源之后需要重新update

Linux管理员修改普通用户密码

  • root修改普通用户的密码

Linux下使用sudo命令出现not in the sudoers file

  • 使用su -命令切换到root身份。注意该命令有-,与su不同,在用命令su的时候只是切换到root,但没有把root的环境变量传过去,还是当前用户的环境变量,用su -命令将环境变量也一起带过去,就像和root登录一样

  • 使用visudo命令编辑sudo权限文件。注意,该命令为一个单词

  • 出现vim编辑窗口,在文件合适位置加入<user_name> ALL=(ALL) ALL语句

  • 保存退出后,便把自己加入了sudo组,可以使用sudo命令了

Linux下安装Miniconda

  1. 进入清华大学开源软件镜像站 - Anaconda镜像使用帮助,下翻找到Miniconda镜像使用帮助

  2. 直接下载对应版本的sh文件,或将光标定位在所需文件,复制链接地址,再使用wget -c <url>下载

  3. 运行该文件,即执行命令bash Miniconda***.sh,根据提示按Enter键或者输入yes即可

  4. 安装完成后,会在家目录~下生成一个Minconda3文件夹

  5. 运行source .bashrc,激活conda,这时会发现终端前出现了(base),表示已进入conda环境

  6. conda安装成功之后,逐行运行下面的命令,添加国内镜像,方便以后下载软件。

  1. 注:若不希望终端前一直显示base,仅在需用conda时才调用,可在.bashrc最后加上一句conda deactivate使其默认不运行。需使用时输入conda activate激活之。

WSL更改登录用户

  • 对于Ubuntu系统,在Windows PowerShell中运行ubuntu config --default-user <username>即可

WSL中Vim字体改变的解决方案

  • 问题:安装好WSL版本的Ubuntu1804之后,由于默认字体不适合长时间阅读且不美观,便从属性窗口设置了新字体,但是发现在启动Vim的时候会出现字体变回原来的字体的情况。

  • 解决方法:运行regedit修改注册表,定位至HKEY_CURRENT_USER\Console\C:_Program Files_WindowsApps_CanonicalGroupLimited.Ubuntu18.04onWindows_1804<...>ubuntu1804.exe,方括号中内容根据实际情况修改,在其中添加:CodePageDWORD类型、值0x01b5

Linux字符串变量操作

截取

  • 示例

  1. 取得字符串长度

  1. 字符串所在位置

  1. 从字符串开头到子串的最大长度

  1. 字符串截取

  1. 匹配内容

  1. 截取不匹配内容

  1. 比较

  1. 连接

删除与替换

  • 巧记方法:#%是删除符号。在键盘上,#$的左边,所以是从左边开始删除,%$的右边,所以是从右边开始删除。/是替换符。

  • 示例

  1. 输出文件的后缀

  1. 输出文件名

  1. 替换部分字符

变量声明

变量声明操作

Linux下nohup命令

nohup英文全称no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。在默认情况下(非重定向时),程序会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,则输出重定向到 $HOME/nohup.out 文件中。

语法格式:

参数说明:

示例:

以下命令在后台执行1.sh脚本,并重定向输出到1.log文件:

如果要停止运行,你需要使用以下命令查找到nohup运行脚本到PID,然后使用kill命令来删除:

耗时很长的程序忘加nohup就运行了怎么办

  • Ctrl+z把程序挂起,操作后屏幕会出现如下提示([1]中的1表示命令的作业号):

  • jobs命令查看下任务状态,跟刚才的屏幕提示一致,程序被暂时终止,作业号还是1:

  • 使用bg %1命令把作业号为1的任务放入后台,并从停止状态变为运行状态,相当于加了&后接着运行。再用jobs查看,任务状态变成了运行中。

  • 运行disown -h %1,表示在终端关闭时不对作业号为1的程序发送终止信号,外部因素将不影响程序的运行。可通过ps命令查看任务进程。

  • 提示:

    • 例子中使用的是rsync同步,从节省时间来看,不是一个很好的例子。因为把命令停掉再运行一次时,已经同步完整的数据不会再同步,时间损失不会太大。这也是使用同步命令rsync相比于scp的一个好处。

    • 例子中的rsync或其它涉及两个服务器交互的命令,都需要我们人为输入登录密码,因此直接加nohup &运行是行不通的,无法接受密码的输入。因此通过上面这个操作先在前台启动运行、输入密码,再放入后台不挂断运行。当然也可以使用ssh免密码登录远程服务器。

    • 如果程序运行时,已加了&放入后台了,则只需运行jobs获得作业号,再运行disown不挂断即可。

    • 程序作业号不一定都是1,如果之前就有程序在后台运行,作业号相应的会自加。

    • nohupdisown都可以使程序不挂断,可以获得一样的效果,但原理不太一致。nohup可以使程序忽略挂断信号(SIGHUP)或者使程序脱离终端的控制,从而终端不能再对其发送挂断信号(SIGHUP);disown则是内生于shell,告诉shell在终止时不对程序发送挂断信号(SIGHUP)。

awk基本操作符、内置函数与变量

awk操作符的优先级

awk操作符

awk内置函数

  • 算术

  • 字符串

  • 其他

  • 完整函数列表请查阅手册

awk内置变量

awk中同样定义了很多内置变量,我们可以直接像使用普通变量一样使用他们,由于awk的版本众多,有些内置变量并不是得到所有awk版本的支持。[A][N][P][G]表示支持该变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk

awk同时处理多个文件

https://www.cnblogs.com/Berryxiong/p/6209332.html

awk的数据输入有两个来源,标准输入和文件,后一种方式支持多个文件。

  1. shellPathname Expansion方式

  1. 直接指定多个文件

那么,在多文件处理的时候,如何判断awk目前读的是哪个文件,而依次做对应的操作呢?

  1. awk读取的文件只有两个的时候,比较常用的方法有:

    1. awk 'NR==FNR{...}NR>FNR{...}' file1 file2

    2. awk 'NR==FNR{...}NR!=FNR{...}' file1 file2

    3. awk 'NR==FNR{...;next}{...}' file1 file2

  2. 了解FNR(已读入当前文件的记录数)和NR(已读入的总记录数)这两个awk内置变量的意义就很容易知道这些方法是如何运作的:

    1. 对于awk 'NR==FNR{...}NR>FNR{...}' file1 file2,读入file1的时候,已读入file1的记录数FNR一定等于awk已读入的总记录数NR,因为file1是awk读入的首个文件,故读入file1时执行前一个命令块{...}。读入file2的时候,已读入的总记录数NR一定大于读入file2的记录数FNR,故读入file2时执行后一个命令块{...}。

    2. 对于awk 'NR==FNR{...;next}{...}' file1 file2,读入file1时,满足NR==FNR,先执行前一个命令块,但因为其中有next命令,故后一个命令块{...}是不会执行的。读入file2时,不满足NR==FNR,前一个命令块{..}不会执行,只执行后一个命令块{...}。

  3. awk处理的文件超过两个时,显然上面那种方法就不适用了。因为读第3个文件或以上时,也满足NR>FNR (NR!=FNR),显然无法区分开来。所以就要用到更通用的方法了:

    1. 利用当前被处理参数标志: awk 'ARGIND==1{...}ARGIND==2{...}ARGIND==3{...}...' file1 file2 file3 ...

    2. 利用命令行参数数组: awk 'FILENAME==ARGV[1]{...}FILENAME==ARGV[2]{...}FILENAME==ARGV[3]{...}...' file1 file2 file3 ...

    3. 把文件名直接加入判断,但不通用: awk 'FILENAME=="file1"{...}FILENAME=="file2"{...}FILENAME=="file3"{...}...' file1 file2 file3 ...

Linux下文件批量重命名

mv命令

rename命令

  • GNU版本:rename old new file_list

    • Example:rename "chr" "" *.gz*

  • perl版本:rename 's/old/new/[g]' file_list

    • Example:rename 's/chr/chrom/g' *.gz*

Bash中括号及expr的用法

小括号()

  • 单小括号(...)

    • 命令组:括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。

    • 命令替换:等同于cmd,shell扫描一遍命令行,发现了(cmd)结构,便将其中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。如a=$(ls) 等同于 a=`ls`

    • 用于初始化数组:如array=(a b c d)

  • 双小括号((...))

    • 整数扩展:这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为0,或者是"False",而一个非零值的表达式所返回的退出状态码将为1,或者是"True"。若表达式是逻辑判断,为真则退出码为1,假则为0。

    • 只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进制运算时,输出结果全都自动转化成了十进制,如echo $((16#5f))的结果为95

    • 单纯用((x))也可重定义变量值,如a=5; ((a++))可将$a重定义为6

    • 双括号中的变量可以不使用$符号前缀。双括号内支持多个表达式用逗号分开。

中括号[]

  • 单中括号[...]

    • bash的内部命令:[test是等同的。如果我们不用绝对路径指明,通常我们用的都是bash自带的命令。if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的,括号两边有空格。这个命令把它的参数作为比较表达式或者作为文件测试,并且根据比较的结果来返回一个退出状态码。

    • test[]中可用的比较运算符只有==!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq-gt这种形式。无论是字符串比较还是整数比较都不支持大于号小于号。如果实在想用,对于字符串比较可以使用转义形式,如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0。[]中的逻辑与和逻辑或使用-a-o表示。

    • 字符范围:用作正则表达式的一部分,描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。

    • 在一个array结构的上下文中,中括号用来引用数组中每个元素的编号。

    • 表达式计算:count=1; echo $[${count} + 1] #result: 2

  • 双中括号[[...]]

    • [[是bash程序语言的关键字,并不是一个命令。[[]]结构比[]结构更加通用。在[[]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。

    • 支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[]]中匹配字符串或通配符不需要引号。

    • 使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。如&&||<>能够正常存在于[[]]条件判断结构中,但在[]结构中会报错。

    • bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。

大括号{}

  • 大括号拓展:通配(globbing)将对大括号中的文件名做扩展。在大括号中,不允许有空白,除非这个空白被引用或转义。

    • 对大括号中的以逗号分割的文件列表进行拓展。如touch {a,b}.txt结果为a.txt b.txt

    • 对大括号中以点点(..)分割的顺序文件列表起拓展作用,如touch {a..d}.txt结果为a.txt b.txt c.txt d.txt

  • 代码块:又称内部组,这个结构事实上创建了一个匿名函数。与小括号中的命令不同,大括号内的命令不会新开一个子shell运行,即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开,最后一个也必须有分号。{}的第一个命令和左括号之间必须要有一个空格。

  • 获取变量:${x}$x

示例

expr用法

  • expr命令是一个手工命令行计数器,用于求表达式变量的值,一般用于整数值,也可用于字符串。

  • 运算表达式用法

  • 运算

  • 正则匹配,返回分组结果,每次只能设定一个分组

  • match用法:从开头匹配,返回字符所在下标(下标从1开始),未匹配返回0,使用通配符时返回最后一个匹配字符所在下标

  • 字符串操作

Linux下按Tab补全命令时忽略大小写

执行vim ~/.inputrc,添加如下内容,保存重启终端后即可。

Linux tar 命令

Linux tar(英文全拼:tape archive )命令用来建立、还原备份文件,它可以加入、解开备份文件内的文件。

语法

参数

示例

  • 压缩文件:tar -czvf test.tar.gz 1.txt #压缩1.txt文件为test.tar.gz

  • 列出压缩文件内容:tar -tzvf test.tar.gz

  • 解压文件:tar -xzvf test.tar.gz

  • 排除目录中的某些文件,然后进行压缩:tar --exclude=folder/*.txt -czvf test.tgz folder

Bash脚本传递参数

位置参数

通过在命令行的位置,来表示传入对应脚本的参数。这是最简单的一种,如下我们将4个参数对应START, END, SCFID 和 GENE 进行传入参数。

这时在执行的时候,只需在命令行输入对应参数即可,参数之间使用空格分割。

这种方法虽然简单,但是输入参数的时候必须严格对应,不能空缺参数,不能颠倒位置,这对脚本的新用户是十分不友好的。

参数处理

  • $#: 传递到脚本的参数个数

  • $*: 以一个单字符串显示所有向脚本传递的参数。如执行"$*",以"$1 $2 … $n"的形式输出所有参数。

  • $$: 脚本运行的当前进程ID号

  • $!: 后台运行的最后一个进程的ID号

  • $@: 在引号中返回每个参数。如执行"$@",以"$1" "$2" … "$n"的形式输出所有参数。

  • 注:$*$@,相同点都是引用所有参数,不同点只有在双引号中体现出来。假设在脚本运行时写了三个参数1、2、3,则"$*"等价于"1 2 3"(传递了一个参数),而"$@"等价于"1" "2" "3"(传递了三个参数)。

  • $-: 显示Shell使用的当前选项,与set命令功能相同。

  • $?: 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

参数名匹配

另一种传递参数的方式就是使用关键词,通过关键词匹配进行参数传递,这种情况下的参数传入方式就比较灵活了,不依赖于参数位置。

这时在命令行,可以不按照顺序输入参数,也可以使用双横线和全称的方式输入:

当然,如果命令参数没有找到匹配,会提示错误:

这种参数传入的方式有两个关键,一个是使用case语句,另一个是使用了shiftshift的作用主要是移动位置参数。每执行一次都讲第一个位置参数向右移动一次。当然,如果是shift n就是每执行一次,向右移动n个位置。参考:https://www.computerhope.com/unix/bash/shift.htm

有时候我们常使用等号=来进行参数传递,整体做法和使用上述空格是一样的。

Linux echo 不换行输出的两种方式

  • 方法一:echo -n text

  • 方法二:echo -e "text\c"

  • echo -e可以处理特殊字符,其后可接的特殊字符有:

Linux下批量中止多个进程

Linux下split命令将一个大文件按行拆分成小文件

sed正则表达式匹配,各种括号的转义和不转义

  • [ ] 需要匹配的时候,需要转义

  • ( ) 需要匹配的时候,不要转义

  • { } 需要匹配的时候,不要转义

  • 当需要匹配数字,字母等使用中括号时候,不要转义;但使用大括号作为特殊字符时(表示前面的字符出现的次数),需要转义

  • 当需要适配符,需要使用\1来替换正则表达式的对应参数时,不能写(regrexxxx),而要写\(regrexxxx\);后面回溯引用写\1

  • 在做为特别字符时候+必须转义为\+才有效,而*则不需要

Sed正则表达式详细介绍

详见此文

行开始 ^

行尾 $

单个字符 .

匹配除行字符结尾的任何单个字符

匹配字符集合 []

匹配这些字符,仅占一个位置

不匹配字符集 [^]

字符范围 [-]

零到一次出现 \?

匹配零次或一次其前面的字符

一次或多次出现 \+

匹配一次或多次其前面的字符

零或多次出现 *

匹配零次或多次其前面的字符

n个重复 \{n\}

共出现n个其前面的字符

最少出现n个 \{n,\}

最少出现n个其前面的字符

m到n次出现 \{m, n\}

\| \(\|\)

awk中的回溯引用 (back references)

详见此文

The usual (and correct) answer for backreferences in awk is: "you can't do backreferences in awk". That is only partly true.

If you need to match a pattern using a regular expression with backreferences, like what you do in sed:

or similar things, then well, you can't do that easily with awk.

But if you are using backreferences during string substitution, to insert text previously captured by a capture group, then you will almost certainly be able to get what you want with awk. Following are some hints:

  • First and easiest answer (requires GNU awk): use gensub(). It supports backreferences natively. Example:

Note that gensub(), unlike sub() and gsub(), returns the modified string without touching the original. Also note that the third parameter is much like sed's match number specification in the s/pattern/replacement/ command: it can either be a number, indicating to replace only that specific match, or the string "g" (as in the example), to indicate replacement of all matches. See the gawk manual for more information (including why backslashes must be escaped in the replacement text).

  • Second answer: sometimes you don't really need backreferences, since what you want can be accomplished without. Examples:

Both things can be done in awk (and sed as well!) without the need of backreferences. You just delete the part of the line you don't need:

Generally speaking, however, the above methods (both sed and awk) require that you have only one matching substring to extract per line. For the same purpose, with some awks (see AwkFeatureComparison), you can use the possibility to assign a regexp to RS to "pull out" substrings from the input (and without the limitation of at most one match per line). See the last part of Pulling out things for more information and examples.

  • Third answer: see GeneralizedTextReplacement for a detailed discussion of a framework for generalized text replacement, including an explanation on how to emulate backreferences (and much more) with awk.

Linux两个文件求交集、并集、差集

定义

  • 交集:两个文件中都出现的行

  • 并集:两个文件中的所有行加起来,去掉重复

  • 差集:在一个文件中存在,而在另一个文件中不存在

方法一:sort+uniq

  • 交集: sort a.txt b.txt | uniq -d (用sort将a.txt b.txt文件进行排序,uniq使得两个文件中的行唯一,使用-d输出两个文件中次数大于1的内容,即是得到交集)

  • 并集: sort a.txt b.txt | uniq (将a.txt b.txt文件进行排序,uniq使得两个文件中的内容为唯一的,即可得到两个文件的并集)

  • 差集:

    • a.txt-b.txt: sort a.txt b.txt b.txt | uniq -u (将两个文件排序,最后输出a.txt b.txt b.txt文件中只出现过一次的内容,因为有两个b.txt所以只会输出只在a.txt出现过一次的内容,即是a.txt-b.txt差集)

    • b.txt-a.txt: sort b.txt a.txt a.txt | uniq -u

  • uniq参数说明:

    • -d 仅显示重复出现的行列

    • -u 仅显示出一次的行列

方法二:comm,用于比较两个已排过序的文件

  • 交集: comm -12 a.txt b.txt

  • 差集:

    • a.txt-b.txt: comm -23 a.txt b.txt

    • b.txt-a.txt: comm -13 a.txt b.txt

  • 注: a.txt b.txt两个文件需要先分别排序;comm默认输出为三列,第一列为是A-B,第二列B-A,第三列为A交B

  • comm参数说明:

    • -1 不显示只在第1个文件里出现过的列

    • -2 不显示只在第2个文件里出现过的列

    • -3 不显示只在第1和第2个文件里出现过的列。

方法三:grep

  • 交集: grep -F -f a.txt b.txt

  • 差集:

    • a.txt-b.txt: grep -F -v -f b.txt a.txt

    • b.txt-a.txt: grep -F -v -f a.txt b.txt

  • 注: grep求交集不要求输入文件是排序的,但最好是唯一的;差集时注意输入文件的顺序

  • grep参数说明:

    • -F 将样式视为固定字符串的列表

    • -f 指定规则文件,其内容含有一个或多个规则样式,查找符合规则条件的文件内容,格式为每行一个规则样式

    • -v 显示不包含匹配文本的所有行

方法四:awk

  • 交集: awk 'NR==FNR{ a[$1]=a[$1]+1} NR>FNR{ if(a[$1]>=1 &&b[$1]<1){ print $1;b[$1]=b[$1]+1}}' a.txt b.txt

  • 差集:

    • a.txt-b.txt: awk 'NR==FNR{a[$1]=$1} NR>FNR{if(a[$1] == ""){print $1}}' b.txt a.txt

    • b.txt-a.txt: awk 'NR==FNR{a[$1]=$1} NR>FNR{if(a[$1] == ""){print $1}}' a.txt b.txt

  • 当NR(表示已经处理的行数)==FNR(表示当前文件处理的行数)时,处理的是a.txt,NR>FNR时,处理的是b.txt,在处理a.txt时,把a数组记录不同字符串个数,且起到去重作用。在处理b.txt时,判断a数组中是否含当前字符串,并且在本文件中出现的次数小于1,同样也是起到了去重的作用。

perl sed awk grep 等对正则表达式的支持的差别

以perl的正则为基准,不同的用法以粉红色标出。

grep 2.5.1

egrep 2.5.1

sed 3.02 sed 4.07

awk 3.1.1

perl 5.8.0

vim 6.1

JavaScript ??

转义

\

\

\

\

\

\

\

行头

^

^

^

^

^

^

^

行尾

$

$

$

$

$

$

$

n个 {n} {m,n} {m,} {,n}

\{n\}

{n}

\{n\}

{n}或\{n\} 仅定义 --posix 或 --re-interval有效(要表达}和{,得用\\{和\\} 没有定义--posix或--re-interval时,不能用{n}的语法, \}\{和}{同义

{n}

\{n\}

{n}

{0,}

*

*

*

*或\*, (要表达*,得用\\*)

*

*

*

{1,}

\+

+

\+

+或\+, (要表达+, 得用\\+)

+

\+

+

{0,1}

\?

?

\?

?或\?, (要表达?, 得用\\?)

?

\?

?

任意字符

.

.

.

. 含\n.

. /s修饰后则含

. 除

. 除

(pat) 匹配并获结果

patpatpatpat

(pat)

patpatpatpat

(pat)或patpatpatpat (要表达括号,用\\( \\) )

(pat)

patpatpatpat

(pat)

(?:pat) 匹配但不获结果

不支持

不支持

不支持

不支持

(?:pat)

不支持

(?:pat)

(?=pat) 等于预查

不支持

不支持

不支持

不支持

(?=pat)

不支持

(?=pat)

(?!pat) 不等预查

不支持

不支持

不支持

不支持

(?!pat)

不支持

(?!pat)

| 或

\|

|

\|

|或\| (要表达|,得用\\|)

|

\|

|

其中任意字符

[xyz]

[xyz]

[xyz]

[xyz]

[xyz]

[xyz]

[xyz]

[.ch.] [=ch=]

不支持

不支持

[.ch.]

不支持

不支持

不支持

不支持

单词边界 \b

\b

\b

\b

不支持

\b

不支持

\b

非单词边界 \B

\B

\B

\B

不支持

\B

不支持

\B

单词左右边界 <>

\< \>

\< \>

\< \>

不支持 (><和\>\<和\\>\\<同义

不支持(><和\>\<同义

\< \>

不支持(><和\>\<同义

控制字符 /cx

不支持

不支持

\cx

不支持

\cx

不支持

\cx

数字\d

不支持

不支持

不支持

不支持

\d

\d

\d

非数字\D

不支持

不支持

不支持

不支持

\D

\D

\D

换页 \f

不支持

不支持

高版本支持

\f

\f

另义 \f表示文件名字符

\f

换行

不支持

不支持

不支持

回车

不支持

不支持

空白 \s

不支持

不支持

不支持

不支持

\s

\s

\s

非空白 \S

不支持

不支持

不支持

不支持

\S

\S

\S

制表符

不支持

不支持

高版本支持

垂直制表符 \v

不支持

不支持

高版本支持

\v

\v

另义 \v表示very magic

\v

单词字符 \w [A-Za-z0-9_]

\w

\w

\w

不支持

\w

\w

\w

非单词字符 \W [^A-Za-z0-9]

\W

\W

\W

不支持

\W

\W

\W

\xn 16进制

不支持

不支持

高版本支持

\xn

\xn

另义 \x表示[0-9A-Za-z]

\xn

\n 八进制

不支持

不支持

不支持

不支持

\n 后向引用

\n 仅取结果可用

\n 仅取结果可用

[:alnum:] 字母和数字

[:alnum:]

[:alnum:]

[:alnum:]

[:alnum:]

[:alnum:]

[:alnum:]

不支持

[:alpha:] 字母

[:alpha:]

[:alpha:]

[:alpha:]

[:alpha:]

[:alpha:]

[:alpha:]

不支持

[:cntrl:] 控制字符

[:cntrl:]

[:cntrl:]

[:cntrl:]

[:cntrl:]

[:cntrl:]

[:cntrl:]

不支持

[:digit:] 数字

[:digit:]

[:digit:]

[:digit:]

[:digit:]

[:digit:]

[:digit:]

不支持

[:graph:] 可打印字符(不含空格)

[:graph:]

[:graph:]

[:graph:]

[:graph:]

[:graph:]

[:graph:]

不支持

[:lower:] 小写

[:lower:]

[:lower:]

[:lower:]

[:lower:]

[:lower:]

[:lower:]

不支持

[:print:] 可打印字符(含空格)

[:print:]

[:print:]

[:print:]

[:print:]

[:print:]

[:print:]

不支持

[:punct:] 标点

[:punct:]

[:punct:]

[:punct:]

[:punct:]

[:punct:]

[:punct:]

不支持

[:space:] 空格

[:space:]

[:space:]

[:space:]

[:space:]

[:space:]

[:space:]

不支持

[:upper:] 大写字母

[:upper:]

[:upper:]

[:upper:]

[:upper:]

[:upper:]

[:upper:]

不支持

[:xdigit:] 16进制数字

[:xdigit:]

[:xdigit:]

[:xdigit:]

[:xdigit:]

[:xdigit:]

[:xdigit:]

不支持

[:return:]

不支持

不支持

不支持

不支持

不支持

[:return:]

不支持

[:tab:]

不支持

不支持

不支持

不支持

不支持

[:tab:]

不支持

[:escape:]

不支持

不支持

不支持

不支持

不支持

[:escape:]

不支持

[:backspace:]

不支持

不支持

不支持

不支持

不支持

[:backspace:]

不支持

使用Xshell登录Linux子系统 (WSL)

习惯用Linux系统的用户,一般喜欢使用xshell通过SSH登录Linux系统,然后在界面优美的命令端操作Linux命令。以下来介绍如何完美使用xshell登录Windows 10 Linux子系统:

  • 查看ip

  • 配置SSH服务

  • 使用Xshell登录

上面命令执行完之后,在xshell中输入用户名和ip就可以通过xshell登录自己电脑的Linux。

  • 配置永久解决方案

通过上面的方法,我们可以通过xshell登录自己电脑的Linux。但是断开之后重新开机,我们又需要重新配置SSH。因此,我们需要配置以下命令下,一劳永逸。

配置好之后,下次开机,只需要在Linux子系统的默认终端运行sh service.sh命令后,关掉终端改用xshell登录即可。

WSL重启方法

https://stackoverflow.com/questions/70567543/cant-restart-wsl2-lxssmanager-hangs-in-stopping-state-how-to-restart

以管理员权限运行Power Shell:

上述命令在有些情况下无法响应,导致LxssManager服务卡在停止中的状态,既无法停止也无法启动。可在services.msc里查看到该服务的状态,发现停止和启动按钮均为灰色。若如此,可用如下命令获得运行LxssManager服务的svchost.exe进程的PID

或者,可以直接在任务管理器的服务里找到LxssManager服务对应的PID(此时若直接结束该服务仍会无响应)。然后,在任务管理器的详细信息里找到该PID对应的svchost.exe进程,结束之。之后便可以正常使用启动命令或直接运行WSL窗口。

conda 创建/删除环境

消除WSL中ls时Windows文件夹背光的方法

https://blog.csdn.net/qq_33882435/article/details/116264702

产生原因

首先,Linux中ls命令是自带配色的,对于某些文件夹是绿色背景色块,其实是一种权限提示,即777权限。绿色表示不安全,当其他人的权限高于所有者或者所属组时就会变成绿色,或者当文件权限大于系统默认给的最大权限时就会变成绿色,文件初始权限是644,如果变成777就会变绿;文件夹初始权限是755,变成777也会变绿;而且颜色和系统有关,修改配色方案或者修改ls显示的颜色都可以把绿色的报警隐藏掉。

这种配色提醒会导致一个问题:linux目录修改为777后,在secureCRT或者mobaxterm中就看不清楚了,背光晃眼,逼死强迫症。

当然,WSL中挂接的Windows下的文件全部默认是777权限的,所以,可想而知,ls时所有的文件夹都是带有背光的。

解决方法

不显示配色

自定义ls命令为ls --color=none

不过这样也会让我们精心设计的配色方案全都失去意义,所以应该不是个治本方法。

对于777的文件夹不显示背景色

在终端中输入:dircolors >> ~/.bashrc

Linux系统中是使用LS_COLORS环境变量负责运行ls命令时看到的颜色。这个dircolors命令会把LS_COLORS的值重定向到.bashrc文件之中。

LS_COLORS键值对以冒号(:)分隔。这些键大部分是预定义的。仅颜色值会更改。该值具有2个或多个用分号(;)分隔的部分。

例如,di = 0 ; 34,这里di意味着颜色应该应用于目录。0表示它是正常大小,而34表示颜色是绿色。如果要为目录使用绿色粗体 ,则颜色代码应为di = 1 ; 34。此处1表示粗体。如果您还想指定背景色,则也可以为其附加代码。例如,如果要在红色背景上使用黄色普通字体,则代码应为di = 1 ; 33 ; 41

可以看到,这里的ow=34;42,34=蓝色,42=绿色背景。我们想要把绿色背景删掉,就改成ow=1;34,然后重新载入bash设置,就可以去掉ls的背光了,并显示与普通文件夹一样的蓝色加粗字体。

附加材料

有的人可能想要改一下ls的字体或者颜色,可以参考下面的设置: 31 = 红色 40 = 黑色背景 0 =默认颜色 32 = 绿色 41 = 红色背景 1 =粗体 33 = 橙色 42 = 绿色背景 4 =下划线 34 = 蓝色 43 = 橙色背景 5 =闪烁文字 35 = 紫色 44 = 蓝色背景 7 =反向字段(交换前景色和背景色) 36 = 青色 45 = 紫色背景 8 =隐藏(不可见) 37 = 灰色 46 = 青色背景 0 =默认颜色 90 = 深灰色 47 = 灰色背景 1 =粗体

附:LS_COLORS的妙用

https://blog.csdn.net/u010119335/article/details/17398595 http://linux-sxs.org/housekeeping/lscolors.html

Here is an easy way to set different colours for different kinds of files when using the ls command.

Add the following lines to the bottom of your ~/.bashrc file:

The first line makes ls use the --color parameter by default, which tells ls to display files in different colours based on the setting of the LS_COLORS variable.

The second line is the tricky one, and what I have worked out so far has been by trial and error. The parameters (di, fi, etc.) refer to different Linux file types. I have worked them out as shown

The *.rpm=90 parameter at the end tells ls to display any files ending in .rpm in the specified colour, in this case colour 90 (dark grey). This can be applied to any types of files (e.g. you could use *.png=35 to make jpeg files appear purple) As many or as few parameters as you like can go into the LS_COLORS variable, as long as the parameters are separated by colons.

Using trial and error (and a little bash script I wrote... my first one ever! :) I worked out all the colour codes, at least my interpretation of them

These can even be combined, so that a parameter like di=5;31;42 in your LS_COLORS variable would make directories appear in flashing red text with a green background!

Setting LS_COLORS does more than just make your ls listings look pretty (although it certainly does do that), it is also very helpful in identifying files while wading through a file system.

One Example:

URL Encoding

http://blooberry.com/indexdot/html/topics/urlencoding.htm

awk中printf的用法

https://www.cnblogs.com/soymilk2019/p/12165545.html

printf函数返回一个带格式的字符串给标准输出。printf语句包括一个加引号的控制串,控制串中可能嵌有若干格式说明和修饰符。控制串后面跟一个逗号,之后是一列由逗号分隔的表达式。printf函数根据控制串中的说明编排这些表达式的格式。与print函数不同的是, printf不会在行尾自动换行。因此,如果要换行,就必须在控制串中提供转义字符。每一个百分号和格式说明都必须有一个对应的变量。要打印百分号就必须在控制串中给出两个百分号。

printf使用的转义字符

转义字符
定义

c

字符

s

字符串

d

十进制整数

ld

十进制长整数

u

十进制无符号整数

lu

十进制无符号长整数

x

十六进制整数

lx

十六进制长整数

o

八进制整数

lo

八进制长整数

e

用科学记数法(e 记数法)表示的浮点数

f

浮点数

g

选用e或f中较短的一种形式

printf的修饰符

字符
定义

-

左对齐修饰符

#

显示8 进制整数时在前面加个0,显示16 进制整数时在前面加0x

+

显示使用d、e、f 和 g 转换的整数时,加上正负号+或-

0

用0而不是空白符来填充所显示的值

printf的格式说明符

格式说明符
功能

%c

打印单个ASCII 字符 printf("The character is %c\n",x) 输出: The character is A

%d

打印一个十进制数 printf("The boy is %d years old\n",y) 输出:The boy is 15 years old

%e

打印数字的e 记数法形式 printf("z is %e\n",z) 打印: z is 2.3e+0 1

%f

打印一个浮点数 printf("z is %f\n", 2.3 * 2) 输出: z is 4.600000

%o

打印数字的八进制 printf("y is %o\n",y) 输出:z is 17

%s

打印一个字符串 print("The name of the culprit is %s\n",$1) 输出:The name of the culprit is Bob Smith

%x

打印数字的十六进制值 printf("y is %x\n",y) 输出:x is f

Shell管道 (pipe, |) 注意事项

https://www.cnblogs.com/wangxin201492/p/5030983.html https://blog.csdn.net/mdx20072419/article/details/103901292

Shell管道会形成一个子Shell,在其中使用循环修改的变量不能传递到主Shell,wait也针对主Shell的后台进程

我的wait为什么不能用

shell的管道|实际上是产生了一级子shell,也就是在(1)中的后台进程echo $line &是主进程子shell的后台进程。而wait只会等待当前进程的后台进程执行完毕,所以(1)在遇到wait语句直接退出了。

(2)中,通过< $file将文件的内容标准输入到while中,并未通过管道输入到while中,所以echo $line &为主shell的后台进程,wait会等待所有的后台进程完成以后退出,

Shell变量while循环内改变无法传递到循环外

shell中使用管道会生成一个子shell,在子shell中使用while、for循环的代码也是在子shell中执行的,所以在循环中的修改的变量只在子shell中有效,当循环结束时,会回到主shell,子shell中修改的变量不会影响主shell中的变量。

Shell中按指定分隔符读取文件字段

https://www.topbyte.cn/2020/04/shell-read-file-with-delimiter/

Shell数组

https://www.runoob.com/linux/linux-shell-array.html

Last updated