Open JackieMium opened 6 years ago
最近处理数据经常需要取某个字符串一部分用来重命名的情况,比如 sample1.fastq.gz 比对到基因组想要取出来 sample1 用来命名生成的 sam 文件或者 log,PC 跑起来太慢 log 不能盯着看结果太多又必须要求重定向。每次都要查一下取子集和输出和错误怎么重定向,自己都烦了,干脆写在这儿了。
sample1.fastq.gz
sample1
sam
Shell 里字符串取子集用到 ${} 这样的命令形式。下面通过例子来说明。
${}
我们先定义了一一个变量: file=/dir1/dir2/dir3/my.file.txt
file=/dir1/dir2/dir3/my.file.txt
下面就用 ${ }分別获得不同的值:
${ }
${file#*/}:拿掉第一个 / 及其左边的字串:dir1/dir2/dir3/my.file.txt ${file##*/}:拿掉最后一个 / 及其左边的字串:my.file.txt ${file#*.}:拿掉第一个 . 及其左边的字串:file.txt ${file##*.}:拿掉最后一个. 及其左边的字串:txt
${file#*/}
/
dir1/dir2/dir3/my.file.txt
${file##*/}
my.file.txt
${file#*.}
.
file.txt
${file##*.}
txt
${file%/*}:拿掉最后一个 / 及其右邊的字串:/dir1/dir2/dir3 ${file%%/*}:拿掉第一个 / 及其右边的字串:(空值) ${file%.*}:拿掉最后一个 . 及其右边的字串:/dir1/dir2/dir3/my.file ${file%%.*}:拿掉第一个 . 及其右边的字串:/dir1/dir2/dir3/my
${file%/*}
/dir1/dir2/dir3
${file%%/*}
${file%.*}
/dir1/dir2/dir3/my.file
${file%%.*}
/dir1/dir2/dir3/my
关于 % 和 # 谁是左谁是右,简单的记法就是看这两个键位在普通 QWERTY 键盘上的位置: # 是去掉左边(在键盘上 # 在 % 的左边) % 是去掉右边(在键盘上 % 在 # 的右边) 符号用一次是最小匹配﹔两个连用就是最大匹配。
%
#
${file:0:5}:提取最左边的 5 个字节:/dir1 ${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2
${file:0:5}
/dir1
${file:5:5}
/dir2
对变量里的的字串作替换: ${file/dir/path}:把第一个 dir 替换为 path:/path1/dir2/dir3/my.file.txt ${file//dir/path}:把全部 dir 替换为 path:/path1/path2/path3/my.file.txt
${file/dir/path}
dir
path
/path1/dir2/dir3/my.file.txt
${file//dir/path}
/path1/path2/path3/my.file.txt
Linux 中有三种标准输入输出,它们分别是STDIN,STDOUT,STDERR,分别对应的数字是0,1,2。
STDIN
STDOUT
STDERR
0
1
2
由于STDOUT与STDERR都会默认显示在终端上,为了区分二者的信息,就有了编号1表示STDOUT,2表示STDERR。
搞清楚标准输入输出和错误输出再来看具体的命令形式就简单多了:
终端执行 $ command 后,默认情况下,执行结果STDOUT作为标准输出和STDERR错误输出(如果有的话)都直接被在终端打印出来,或者说终端直接显示出来。
$ command
终端执行$ command 1> out.txt 2> err.txt 后,会将STDOUT与STDERR分别存放至out.txt 和 err.txt 中。该命令也可以写成下面三种形式
$ command 1> out.txt 2> err.txt
out.txt
err.txt
$ command > out.txt 2> err.txt $ command 2> err.txt >out.txt $ command 2> err.txt 1> out.txt
即顺序谁前谁后无所谓,而且默认输出就是 1,所以它是可以直接省略掉的。
$ command > file 2>&1 命令里, & 并不是后台或者 AND 的意思,放在>后面的&,表示重定向的目标不是一个普通文件,而是一个文件描述符,是标准输入输出这些。所以2> 1 代表将 STDERR 即错误输出重定向到当前路径下文件名为 1 的 普通文件 中,而 2> &1 却是代表将重定向到标准输出。而由于标准输出已经被重定向到 file 中,因此最终的结果为标准输出和错误输出都被重定向到 file 中。 &> file 是一种特殊的用法,也可以写成 >& file,二者的意思完全相同,都等价于 >file 2> &1,这里&> 或者 >& 都应该视作整体,分开没有单独的含义。
$ command > file 2>&1
&
>
文件描述符
2> 1
普通文件
2> &1
file
&> file
>& file
>file 2> &1
&>
>&
最近处理数据经常需要取某个字符串一部分用来重命名的情况,比如
sample1.fastq.gz
比对到基因组想要取出来sample1
用来命名生成的sam
文件或者 log,PC 跑起来太慢 log 不能盯着看结果太多又必须要求重定向。每次都要查一下取子集和输出和错误怎么重定向,自己都烦了,干脆写在这儿了。字符串取子集
Shell 里字符串取子集用到
${}
这样的命令形式。下面通过例子来说明。我们先定义了一一个变量:
file=/dir1/dir2/dir3/my.file.txt
下面就用
${ }
分別获得不同的值:${file#*/}
:拿掉第一个/
及其左边的字串:dir1/dir2/dir3/my.file.txt
${file##*/}
:拿掉最后一个/
及其左边的字串:my.file.txt
${file#*.}
:拿掉第一个.
及其左边的字串:file.txt
${file##*.}
:拿掉最后一个.
及其左边的字串:txt
${file%/*}
:拿掉最后一个/
及其右邊的字串:/dir1/dir2/dir3
${file%%/*}
:拿掉第一个/
及其右边的字串:(空值)${file%.*}
:拿掉最后一个.
及其右边的字串:/dir1/dir2/dir3/my.file
${file%%.*}
:拿掉第一个.
及其右边的字串:/dir1/dir2/dir3/my
关于
%
和#
谁是左谁是右,简单的记法就是看这两个键位在普通 QWERTY 键盘上的位置:#
是去掉左边(在键盘上#
在%
的左边)%
是去掉右边(在键盘上%
在#
的右边) 符号用一次是最小匹配﹔两个连用就是最大匹配。${file:0:5}
:提取最左边的 5 个字节:/dir1
${file:5:5}
:提取第 5 个字节右边的连续 5 个字节:/dir2
对变量里的的字串作替换:
${file/dir/path}
:把第一个dir
替换为path
:/path1/dir2/dir3/my.file.txt
${file//dir/path}
:把全部dir
替换为path
:/path1/path2/path3/my.file.txt
重定向
Linux 中有三种标准输入输出,它们分别是
STDIN
,STDOUT
,STDERR
,分别对应的数字是0
,1
,2
。STDIN
是标准输入,默认从键盘读取信息;STDOUT
是标准输出,默认将输出结果输出至终端;STDERR
是标准错误,默认将输出结果输出至终端。由于
STDOUT
与STDERR
都会默认显示在终端上,为了区分二者的信息,就有了编号1
表示STDOUT
,2
表示STDERR
。搞清楚标准输入输出和错误输出再来看具体的命令形式就简单多了:
终端执行
$ command
后,默认情况下,执行结果STDOUT
作为标准输出和STDERR
错误输出(如果有的话)都直接被在终端打印出来,或者说终端直接显示出来。终端执行
$ command 1> out.txt 2> err.txt
后,会将STDOUT
与STDERR
分别存放至out.txt
和err.txt
中。该命令也可以写成下面三种形式即顺序谁前谁后无所谓,而且默认输出就是
1
,所以它是可以直接省略掉的。$ command > file 2>&1
命令里,&
并不是后台或者 AND 的意思,放在>
后面的&
,表示重定向的目标不是一个普通文件,而是一个文件描述符
,是标准输入输出这些。所以2> 1
代表将STDERR
即错误输出重定向到当前路径下文件名为1
的普通文件
中,而2> &1
却是代表将重定向到标准输出。而由于标准输出已经被重定向到file
中,因此最终的结果为标准输出和错误输出都被重定向到file
中。&> file
是一种特殊的用法,也可以写成>& file
,二者的意思完全相同,都等价于>file 2> &1
,这里&>
或者>&
都应该视作整体,分开没有单独的含义。