liuyujie0136's Website

Logo

A website for self learning, collecting and sharing.

Contact Me

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创建共享文件夹

鳥哥的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查看系统基本信息

Bash和Sh的区别

Bash is the most commonly used linux shell.

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

示例一

# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific environment and startup programs
if [ -f $HOME/shortcuts ]; then
        source $HOME/shortcuts
fi
PATH=$HOME/bin:$PATH
export PATH

# User specific aliases and functions
alias qstat="qstat -u '*'"
#alias screen="/usr/bin/screen -D -R"
#alias rm="$HOME/bin/del.sh"
#alias undel="$HOME/bin/del.sh -u"
#alias ls="ls --color"
alias ld="ls -d"
alias c="clear"
alias l="ls -alh"
alias lf="ls -F|grep /"
alias lt="ls -tlr"
alias mv="mv -i"
alias cp="cp -pi"
alias diff="diff -b"

#PERL5LIB=$MYHOME/perllib:$MYHOME/perllib/lib64/perl5/site_perl/5.8.5:$MYHOME/perlib/lib/perl5/site_perl/5.8.5
#export PERL5LIB
#export R_LIBS_USER=~/R:/data/apps/R_library

示例二

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # We have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
    # a case would tend to support setf rather than setaf.)
    color_prompt=yes
    else
    color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

# personal alias
alias c="clear"
alias ca="cat -A"

利用.vimrc个性化配置vim

Bash下使用rsynccrontab备份文件

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

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

alias today="date +F%"  # +F% format is like 2020-01-01
mkdir results-$(today)

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

ls -F | grep '/$'   #最易用,若将其结果保存在变量里,可用循环遍历并用cd访问
ls -l | grep '^d'   #显示信息最完整

附:ls与cd连用示例

#!/bin/bash
dir=`ls -F | grep "/$"`
for i in $dir
do
    cd $i
    files=`ls`  # or files=$(ls)
    for j in $files
    do
        cat $j >> /home/test/share/all.out
    done
    cd ..
done
exit 0

Linux下替换^M字符方法

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

cat -A text.txt
1^M$
2^M$
3^M$
4^M$
5^M$
6^M$
7^M$
8^M$

有如下解决方法:

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

# 先设置用户名和密码
git config --global user.email "test@foo.com"
git config --global user.name "test"

# 提交时将CRLF转换为LF,拉取时不将LF转换为CRLF
# 配合VS Code设置默认EOL为`\n`(LF),可使所有文件格式保持为LF
git config --global core.autocrlf input
# 也可设置为false,拒绝所有转换,但需保证项目所有参与者均用LF提交

# 拒绝提交包含混合换行符的文件
git config --global core.safecrlf true

# 查看配置
git config --global --list

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

Linux中cut命令

Ubuntu镜像使用帮助

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

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

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

Linux下安装Miniconda

  1. 进入清华大学开源软件镜像站 - Anaconda镜像使用帮助,下翻找到Miniconda镜像使用帮助
  2. 进入Miniconda安装包下载地址
  3. 直接下载对应版本的sh文件,或将光标定位在所需文件,复制链接地址,再使用wget -c <url>下载
  4. 运行该文件,即执行命令bash Miniconda***.sh,根据提示按Enter键或者输入yes即可
  5. 安装完成后,会在家目录~下生成一个Minconda3文件夹
  6. 运行source .bashrc,激活conda,这时会发现终端前出现了(base),表示已进入conda环境
  7. conda安装成功之后,逐行运行下面的命令,添加国内镜像,方便以后下载软件。
      conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
      conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
      conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda
      conda config --set show_channel_urls yes
    
  8. 注:若不希望终端前一直显示base,仅在需用conda时才调用,可在.bashrc最后加上一句conda deactivate使其默认不运行。需使用时输入conda activate激活之。

WSL更改登录用户

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

Linux字符串变量操作

截取

${#var}         变量长度
${var:pos}      从位置pos至结尾提取子串(位置从0开始)
${var:pos:len}  从位置pos开始提取长度为len的子串

删除与替换

变量声明

变量声明操作

Linux下nohup命令

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

语法格式:

nohup Command [ Args ] [ & ]

参数说明:

Command  要执行的命令。
Args     一些参数,可以指定输出文件。
&        让命令在后台执行,终端退出后命令仍旧执行。

示例:

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

nohup 1.sh > 1.log 2>&1 &

# 2>&1: 将标准错误2重定向到标准输出&1,标准输出&1再被重定向输出到1.log文件中
# 0 – stdin (standard input,标准输入)
# 1 – stdout (standard output,标准输出)
# 2 – stderr (standard error,标准错误输出)

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

ps -aux | grep "1.sh" 
kill -9 <PID>

# 参数说明:
a   显示所有程序
u   以用户为主的格式来显示
x   显示所有程序,不区分终端机

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

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

awk操作符的优先级

awk操作符

awk内置函数

awk内置变量

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

[A] $k          当前记录的第k个字段(列)
[A] $0          当前行文本内容
[N] ARGC        命令行参数的数目
[G] ARGIND      命令行中当前文件的位置(从0开始)
[N] ARGV        包含命令行参数的数组
[G] CONVFMT     数字转换格式(默认值为%.6g)
[P] ENVIRON     环境变量关联数组
[N] ERRNO       最后一个系统错误的描述
[G] FIELDWIDTHS 字段宽度列表(用空格键分隔)
[A] FILENAME    当前输入文件的名
[P] FNR         同NR,但相对于当前文件
[A] FS          字段分隔符(默认是任何空格)
[G] IGNORECASE  如果为真,则进行忽略大小写的匹配
[A] NF          表示字段数,在执行过程中对应于当前的字段数
[A] NR          表示记录数,在执行过程中对应于当前的行号
[A] OFMT        数字的输出格式(默认值是%.6g)
[A] OFS         输出字段分隔符(默认值是一个空格)
[A] ORS         输出记录分隔符(默认值是一个换行符)
[A] RS          记录分隔符(默认是一个换行符)
[N] RSTART      由match函数所匹配的字符串的第一个位置
[N] RLENGTH     由match函数所匹配的字符串的长度
[N] SUBSEP      数组下标分隔符(默认值是34)

awk同时处理多个文件

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

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

  1. shellPathname Expansion方式
    awk '{...}' *.txt
    # *.txt先被shell解释,替换成当前目录下的所有*.txt,如当前目录有1.txt和2.txt,则命令最终为awk '{...}' 1.txt 2.txt
    
  2. 直接指定多个文件
    awk '{...}' a.txt b.txt c.txt ...
    # awk对多文件的处理流程是,依次读取各个文件内容,先读a.txt,再读b.txt....
    

那么,在多文件处理的时候,如何判断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命令

for i in `ls *.gz`
do
    mv $i ${i:0:5}  #Example:仅截取从首位开始的五位作为文件名
done

rename命令

Bash中括号及expr的用法

小括号()

中括号[]

大括号{}

示例

if ($i<5)
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4); do echo $i; done
for i in `seq 0 4`; do echo $i; done
for ((i=0;i<5;i++)); do echo $i; done
for i in {0..4}; do echo $i; done

expr用法

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

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

set completion-ignore-case on

Linux tar 命令

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

语法

tar [-ABcdgGhiklmMoOpPrRsStuUvwWxzZ][-b <区块数目>][-C <目的目录>][-f <备份文件>][-F <Script文件>][-K <文件>][-L <媒体容量>][-N <日期时间>][-T <范本文件>][-V <卷册名称>][-X <范本文件>][-<设备编号><存储密度>][--after-date=<日期时间>][--atime-preserve][--backuup=<备份方式>][--checkpoint][--concatenate][--confirmation][--delete][--exclude=<范本样式>][--force-local][--group=<群组名称>][--help][--ignore-failed-read][--new-volume-script=<Script文件>][--newer-mtime][--no-recursion][--null][--numeric-owner][--owner=<用户名称>][--posix][--erve][--preserve-order][--preserve-permissions][--record-size=<区块数目>][--recursive-unlink][--remove-files][--rsh-command=<执行指令>][--same-owner][--suffix=<备份字尾字符串>][--totals][--use-compress-program=<执行指令>][--version][--volno-file=<编号文件>][文件或目录...]

参数

-A或--catenate    #新增文件到已存在的备份文件。
-b<区块数目>或--blocking-factor=<区块数目>    #设置每笔记录的区块数目,每个区块大小为12Bytes。
-B或--read-full-records    #读取数据时重设区块大小。
-c或--create    #建立新的备份文件。
-C<目的目录>或--directory=<目的目录>    #切换到指定的目录。
-d或--diff或--compare    #对比备份文件内和文件系统上的文件的差异。
-f<备份文件>或--file=<备份文件>    #指定备份文件。
-F<Script文件>或--info-script=<Script文件>    #每次更换磁带时,就执行指定的Script文件。
-g或--listed-incremental    #处理GNU格式的大量备份。
-G或--incremental    #处理旧的GNU格式的大量备份。
-h或--dereference    #不建立符号连接,直接复制该连接所指向的原始文件。
-i或--ignore-zeros    #忽略备份文件中的0 Byte区块,也就是EOF。
-k或--keep-old-files    #解开备份文件时,不覆盖已有的文件。
-K<文件>或--starting-file=<文件>    #从指定的文件开始还原。
-l或--one-file-system    #复制的文件或目录存放的文件系统,必须与tar指令执行时所处的文件系统相同,否则不予复制。
-L<媒体容量>或-tape-length=<媒体容量>    #设置存放每体的容量,单位以1024 Bytes计算。
-m或--modification-time    #还原文件时,不变更文件的更改时间。
-M或--multi-volume    #在建立,还原备份文件或列出其中的内容时,采用多卷册模式。
-N<日期格式>或--newer=<日期时间>    #只将较指定日期更新的文件保存到备份文件里。
-o或--old-archive或--portability    #将资料写入备份文件时使用V7格式。
-O或--stdout    #把从备份文件里还原的文件输出到标准输出设备。
-p或--same-permissions    #用原来的文件权限还原文件。
-P或--absolute-names    #文件名使用绝对名称,不移除文件名称前的"/"号。
-r或--append    #新增文件到已存在的备份文件的结尾部分。
-R或--block-number    #列出每个信息在备份文件中的区块编号。
-s或--same-order    #还原文件的顺序和备份文件内的存放顺序相同。
-S或--sparse    #倘若一个文件内含大量的连续0字节,则将此文件存成稀疏文件。
-t或--list    #列出备份文件的内容。
-T<范本文件>或--files-from=<范本文件>    #指定范本文件,其内含有一个或多个范本样式,让tar解开或建立符合设置条件的文件。
-u或--update    #仅置换较备份文件内的文件更新的文件。
-U或--unlink-first    #解开压缩文件还原文件之前,先解除文件的连接。
-v或--verbose    #显示指令执行过程。
-V<卷册名称>或--label=<卷册名称>    #建立使用指定的卷册名称的备份文件。
-w或--interactive    #遭遇问题时先询问用户。
-W或--verify    #写入备份文件后,确认文件正确无误。
-x或--extract或--get    #从备份文件中还原文件。
-X<范本文件>或--exclude-from=<范本文件>    #指定范本文件,其内含有一个或多个范本样式,让ar排除符合设置条件的文件。
-z或--gzip或--ungzip    #通过gzip指令处理备份文件。
-Z或--compress或--uncompress    #通过compress指令处理备份文件。
-<设备编号><存储密度>    #设置备份用的外围设备编号及存放数据的密度。
--after-date=<日期时间>    #此参数的效果和指定"-N"参数相同。
--atime-preserve    #不变更文件的存取时间。
--backup=<备份方式>或--backup    #移除文件前先进行备份。
--checkpoint    #读取备份文件时列出目录名称。
--concatenate    #此参数的效果和指定"-A"参数相同。
--confirmation    #此参数的效果和指定"-w"参数相同。
--delete    #从备份文件中删除指定的文件。
--exclude=<范本样式>    #排除符合范本样式的文件。
--group=<群组名称>    #把加入设备文件中的文件的所属群组设成指定的群组。
--help    #在线帮助。
--ignore-failed-read    #忽略数据读取错误,不中断程序的执行。
--new-volume-script=<Script文件>    #此参数的效果和指定"-F"参数相同。
--newer-mtime    #只保存更改过的文件。
--no-recursion    #不做递归处理,也就是指定目录下的所有文件及子目录不予处理。
--null    #从null设备读取文件名称。
--numeric-owner    #以用户识别码及群组识别码取代用户名称和群组名称。
--owner=<用户名称>    #把加入备份文件中的文件的拥有者设成指定的用户。
--posix    #将数据写入备份文件时使用POSIX格式。
--preserve    #此参数的效果和指定"-ps"参数相同。
--preserve-order    #此参数的效果和指定"-A"参数相同。
--preserve-permissions    #此参数的效果和指定"-p"参数相同。
--record-size=<区块数目>    #此参数的效果和指定"-b"参数相同。
--recursive-unlink    #解开压缩文件还原目录之前,先解除整个目录下所有文件的连接。
--remove-files    #文件加入备份文件后,就将其删除。
--rsh-command=<执行指令>    #设置要在远端主机上执行的指令,以取代rsh指令。
--same-owner    #尝试以相同的文件拥有者还原文件。
--suffix=<备份字尾字符串>    #移除文件前先行备份。
--totals    #备份文件建立后,列出文件大小。
--use-compress-program=<执行指令>    #通过指定的指令处理备份文件。
--version    #显示版本信息。
--volno-file=<编号文件>    #使用指定文件内的编号取代预设的卷册编号。

示例

Bash脚本传递参数

位置参数

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

#!/bin/bash

START=${1}
END=${2}
SCFID=${3}
GENE=${4}

echo The ${GENE} is on Chr${SCFID}:${START}-${END} 

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

bash gene.sh 5000000 6000000 785 Cyp6a9
## The Cyp6a9 is on Chr785:5000000-6000000

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

参数处理

参数名匹配

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

#!/bin/bash
usage() {
  echo "Usage: ${0} [-s|--start] [-e|--end] [-i|--scfid] [-g|--gene]" 1>&2
  exit 1 
}
while [[ $# -gt 0 ]];do
  key=${1}
  case ${key} in
    -s|--start)
      START=${2}
      shift 2
      ;;
    -e|--end)
      END=${2}
      shift 2
      ;;
    -i|--scfid)
      SCFID=${2}
      shift 2
      ;;
    -g|--gene)
      GENE=${2}
      shift 2
      ;;
    *)
      usage
      shift
      ;;
  esac
done
    
echo The ${GENE} is on Chr${SCFID}:${START}-${END}

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

bash gene.sh -s 5000000 -e 6000000 -i 785 -g Cyp6a2 
bash gene.sh -e 6000000 -i 785 -g Cyp6a2 -s 5000000
bash gene.sh -e 6000000 -i 785 --gene Cyp6a2 -s 5000000
## ...

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

bash gene.sh dsafda
## Usage: ./gene.sh [-s|--start] [-e|--end] [-i|--scfid] [-g|--gene]

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

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

bash gene.sh -s=5000000 -e=6000000 -i=785 -g=Cyp6a2 

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

Linux下批量中止多个进程

ps -f | grep python | grep -v grep | cut -c 9-15 | xargs kill -9

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

split [OPTION]... [FILE [PREFIX]]
-l  指定行数,每个文件多少行
-b  指定大小,每个文件100M,这种可能会破坏一行的完整性
-d  指定用数字递增为生成的文件名编号,最后以test为前缀
-a  指定有几位数字作为后缀,这里指定了2位,则从00开始

split -l 7000 1.csv -d -a 2 test
split -b 100M 1.csv -d -a 2 test

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

行开始 ^

sed -n '/^The/p' books.txt

行尾 $

sed -n '/Coelho$/p' books.txt

单个字符 .

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

echo -e "cat\nbat\nrat\nmat\nbatting\nrats\nmats" | sed -n '/^..t$/p'

匹配字符集合 []

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

echo -e "Call\nTall\nBall" | sed -n '/[CT]all/ p'

不匹配字符集 [^]

echo -e "Call\nTall\nBall" | sed -n '/[^CT]all/ p'

字符范围 [-]

echo -e "Call\nTall\nBall" | sed -n '/[C-Z]all/ p'

零到一次出现 \?

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

echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/ p'

一次或多次出现 \+

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

echo -e "111\n22\n123\n234\n456\n222" | sed -n '/2\+/ p'

零或多次出现 *

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

echo -e "ca\ncat" | sed -n '/cat*/ p' 

n个重复 \{n\}

共出现n个其前面的字符

sed -n '/^[0-9]\{3\}$/p' numbers.txt

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

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

sed -n '/^[0-9]\{5,\}$/p' numbers.txt

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

sed -n '/^[0-9]\{5,8\}$/p' numbers.txt

\| \(\|\)

echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/p'
echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str1\|3/p'

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:

sed -n '/\(foo\)\(bar\).*\2\1/p'  # prints lines with "foobar" and "barfoo" later in the line

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:

# reverse letter and following digit and insert "+" if letter is "a" or "c"
echo 'a1-b2-c3-a5-s6-a7-f8-e9-a0' | gawk '{print gensub(/([ac])([0-9])/,"\\2+\\1","g",$0)}'
# outcome: 1+a-b2-3+c-5+a-s6-7+a-f8-e9-0+a

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).

echo 'foo123bar' | sed 's/.*\([0-9]\{1,\}\).*/\1/'
echo 'blah <a href="http://some.site.tld/page1.html">blah blah</a>' | sed 's/.*"\([^"]*\)".*/\1/'

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:

awk '{gsub(/^[a-z]*|[a-z]*$/,""); print}'   # 1st example
awk '{gsub(/^[^"]*"|"[^"]*$/,""); print}'   # 2nd example

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.

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

定义

方法一:sort+uniq

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

方法三:grep

方法四:awk

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修饰后则含\n

. 除\n

. 除\n

(pat) 匹配并获结果

pat

(pat)

pat

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

(pat)

pat

(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

换行 \n

不支持

不支持

不支持

\n

\n

\n

\n

回车 \r

不支持

不支持

\r

\r

\r

\r

\r

空白 \s

不支持

不支持

不支持

不支持

\s

\s

\s

非空白 \S

不支持

不支持

不支持

不支持

\S

\S

\S

制表符 \t

不支持

不支持

高版本支持

\t

\t

\t

\t

垂直制表符 \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

\n 后向引用

\n

\n

\n

\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子系统:

sudo apt-get remove --purge openssh-server   ## 先删ssh
sudo apt-get install openssh-server          ## 在安装ssh  

sudo rm /etc/ssh/ssh_config                  ## 删配置文件,让ssh服务自己想办法链接
sudo service ssh --full-restart

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

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

sudo service ssh --full-restart   ## 可将该命令保存为service.sh,存在home目录下

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

WSL重启方法

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

以管理员权限运行Power Shell:

net stop LxssManager
net start LxssManager

# OR:
sc.exe queryex LxssManager
sc.exe stop LxssManager
sc.exe start LxssManager
sc.exe queryex LxssManager

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

tasklist /svc /fi "imagename eq svchost.exe" | findstr LxssManager

# OR:
Get-CimInstance -ClassName Win32_Service -Filter "Name='LxssManager'"

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

conda 创建/删除环境

conda create --name envName python=3.7
conda create --name envName python=3.9 numpy scipy
conda env list
conda remove --name envName --all

消除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:

alias ls='ls --color'
LS_COLORS='di=1:fi=0:ln=31:pi=5:so=5:bd=5:cd=5:or=31:mi=0:ex=35:*.rpm=90'
export LS_COLORS

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

di = directory  
fi = file  
ln = symbolic link  
pi = fifo file  
so = socket file  
bd = block (buffered) special file  
cd = character (unbuffered) special file  
or = symbolic link pointing to a non-existent file (orphan)  
mi = non-existent file pointed to by a symbolic link (visible when you type ls -l)  
ex = file which is executable (ie. has 'x' set in permissions).

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

0   = default colour  
1   = bold  
4   = underlined  
5   = flashing text  
7   = reverse field  
31 = red  
32 = green  
33 = orange  
34 = blue  
35 = purple  
36 = cyan  
37 = grey  
40 = black background  
41 = red background  
42 = green background  
43 = orange background  
44 = blue background  
45 = purple background  
46 = cyan background  
47 = grey background  
90 = dark grey  
91 = light red  
92 = light green  
93 = yellow  
94 = light blue  
95 = light purple  
96 = turquoise  
100 = dark grey background  
101 = light red background  
102 = light green background  
103 = yellow background  
104 = light blue background  
105 = light purple background  
106 = turquoise background

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:

LS_COLORS='no=00:fi=00:di=01;33:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=0  
1;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32  
:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;3  
1:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm  
=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:'  

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不会在行尾自动换行。因此,如果要换行,就必须在控制串中提供转义字符\n。每一个百分号和格式说明都必须有一个对应的变量。要打印百分号就必须在控制串中给出两个百分号。

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