Linux:管线命令

http://blog.csdn.net/pipisorry/article/details/39760961linux

当Linux执行一个程序的时候,会自动打开三个流,标准输入(standard input),标准输出(standard output),标准错误(standard error)。好比说你打开命令行的时候,默认状况下,命令行的标准输入链接到键盘,标准输出和标准错误都链接到屏幕。git

<符号改变标准输入正则表达式

好比cat命令,它能够从标准输入读入文本流,并输出到标准输出:算法

$cat < a.txtshell

咱们将cat标准输入指向a.txt,文本会从文件流到cat,而后再输出到屏幕上。segmentfault

同时从新定向标准输出
bash

$cat < a.txt > b.txtless

使用>&来同时从新定向标准输出和标准错误。工具

若是只想从新定向标准错误,可使用2>。post

管线命令 (pipe)

管线命令在 bash 的连续的处理程序中是至关重要的,在 log file 的分析当中也是至关重要的一环。

Note: 管线命令前面命令的输出可使用{}收集。

撷取命令: cut, grep
排序命令: sort, uniq, wc
双向重导向: tee
字符转换命令: tr, col, join, paste, expand
分割命令: split
参数代换: xargs
关于减号 - 的用途

皮皮blog



撷取命令: cut, grep

linux cut命令

$ cut -d'分隔字符' -f fields &lt;==用于有特定分隔字符

$ cut -c 字符区间 &lt;==用于排列整齐的讯息

选项与参数:
-d  :后面接分隔字符。与 -f 一块儿使用;
-f  :依据 -d 的分隔字符将一段讯息分区成为数段,用 -f 取出第几段的意思;
-c  :以字符 (characters) 的单位取出固定字符区间;这样不就是对字符串取子串操做么

去除字符串前两位字符

find . -size +100M ! -path *git* | cut -c 3-

linux grep命令

做用
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是全部用户。

有一点要注意,您必需提供一个文件过滤方式(搜索所有文件的话用 *)。若是您忘了,’grep’会一直等着,直到该程序被中断。若是您遇到了这样的状况,按 <CTRL c> ,而后再试。

grep 则是分析一行讯息, 若当中有咱们所须要的信息,就将该行拿出来~

格式

-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-s:不显示不存在或无匹配文本的错误信息。$ grep [-acinv] [--color=auto] '搜寻字串' filename
选项与参数:
-a :将 binary 文件以 text 文件的方式搜寻数据
-c :计算找到 '搜寻字串' 的次数,只输出匹配行的计数
-i :忽略大小写的不一样,因此大小写视为相同(只适用于单字符)
-n :顺便输出行号,显示匹配行及行号。
-v :反向选择,亦即显示出没有 '搜寻字串' 内容的那一行!
--color=auto :能够将找到的关键字部分加上颜色的显示喔!

pattern正则表达式主要参数:
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达式的行开始。
\>:到匹配正则表达式的行结束。

\< 和 \> 分别标注单词的开始与结尾。例如:
grep man * 会匹配 ‘Batman’、’manic’、’man’等,
grep ‘\<man’ * 匹配’manic’和’man’,但不是’Batman’,
grep ‘\<man\>’ 只匹配’man’,而不是’Batman’或’manic’等其余的字符串。[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:全部的单个字符。应该是英文句号?
* :有字符,长度能够为0。

下面还有一些有意思的命令行参数:
grep -l pattern files :只列出匹配的文件名,
grep -L pattern files :列出不匹配的文件名,
grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
grep -C number pattern files :匹配的上下文分别显示[number]行,
grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

4.grep命令使用简单实例

$ grep ‘test’ d*
显示全部以d开头的文件中包含 test的行。
$ grep ‘test’ aa bb cc
显示在aa,bb,cc文件中匹配test的行。
$ grep ‘[a-z]\{5\}’ aa
显示全部包含每一个字符串至少有5个连续小写字符的字符串的行。
$ grep ‘w\(es\)t.*\1′ aa
若是west被匹配,则es就被存储到内存中,并标记为1,而后搜索任意个字符(.*),这些字符后面紧跟着 另一个es(\1),找到就显示该行。若是用egrep或grep -E,就不用”\”号进行转义,直接写成’w(es)t.*\1′就能够了。

5.grep命令使用复杂实例

假设您正在’/usr/src/Linux/Doc’目录下搜索带字符 串’magic’的文件:
$ grep magic /usr/src/Linux/Doc/*
sysrq.txt:* How do I enable the magic SysRQ key?
sysrq.txt:* How do I use the magic SysRQ key?
其中文件’sysrp.txt’包含该字符串,讨论的是 SysRQ 的功能。
默认状况下,’grep’只搜索当前目录。若是 此目录下有许多子目录,’grep’会以以下形式列出:
grep: sound: Is a directory
这可能会使’grep’ 的输出难于阅读。这里有两种解决的办法:
明确要求搜索子目录:grep -r
或忽略子目录:grep -d skip
若是有不少 输出时,您能够经过管道将其转到’less’上阅读:
$ grep magic /usr/src/Linux/Documentation/* | less
这样,您就能够更方便地阅读。

grep字符串搜索算法

grep速度快的一个重要缘由是使用了Boyer-Moore算法做为字符串搜索算法

[为何GNU grep如此之快?]

grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)

[grep之字符串搜索算法Boyer-Moore由浅入深]

皮皮Blog



排序命令: sort, uniq, wc

linux sort命令

排序的字符与语系的编码有关,所以, 若是您须要排序时,建议使用 LANG=C 来让语系统一,数据排序比较好一些。

$ sort [-fbMnrtuk] [file or stdin]
选项与参数:
-f  :忽略大小写的差别,例如 A 与 a 视为编码相同;
-b  :忽略最前面的空白字符部分;
-M  :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
-n  :使用“纯数字”进行排序(默认是以文字体态来排序的);
-r  :反向排序;
-u :就是 uniq ,相同的数据中,仅出现一行表明;
-t  :分隔符号,默认是用 [tab] 键来分隔;
-k  :以那个区间 (field) 来进行排序的意思

linux uniq命令

将重复的数据仅列出一个显示

[dmtsai@study ~]$ uniq [-ic]
选项与参数:
-i  :忽略大小写字符的不一样;
-c  :进行计数

Note: 特别要注意的地方: 'uniq'  does not detect repeated lines unless they are adjacent.  You may want to sort the input first, or use 'sort -u' without  'uniq'.   Also,  comparisons honor the rules specified by 'LC_COLLATE'.

也就是在使用uniq以前要进行排序,不然相隔的相同字符不会去重。这样的话,直接使用sort -nu最好了。

pipi@pipicmp:~/files/DATASETS/tianchi/ccf_data_revised$ cat ccf_online_stage1_train.csv | cut -d ',' -f 2 | uniq | sort -n | head
10001
10001
10001...
10001
pipi@pipicmp:~/files/DATASETS/tianchi/ccf_data_revised$ cat ccf_online_stage1_train.csv | cut -d ',' -f 2 | sort -n | uniq | head
10001
10002
10003
10004...
10009
10010

linux wc命令

要知道文件里面有多少字?多少行?多少字符?

$ wc [-lwm]
选项与参数:
-l  :仅列出行;
-w  :仅列出多少字(英文单字);
-m  :多少字符;

统计项目中的代码行数cloc

cloc可以统计包括:代码行数、注释、空行、文件大小等数据。另外,还支持对软件开发项目的各个开发阶段的工数、成本、质量指标等进行分析和预测。

$ sudo apt-get install cloc

SocialNetworks$ cloc .

[cloc网站]

直接写简单的能够这样:

find . \( -path ./tmp_data -o -path ./gowalla-exp \) -prune -o \( -name '*.pyc' -o -name '*.py' -type f \) -print | xargs -0 cat | grep -v -e ^$ -e ^\s*\#.*$ | wc -l | more

[怎么统计一个工程的代码行数]

[一句shell命令搞定代码行数统计]

皮皮blog



字符转换命令: tr, col, join, paste, expand

tr

tr 能够用来删除一段讯息当中的文字,或者是进行文字讯息的替换!
$ tr [-ds] SET1 ...
选项与参数:
-d  :删除讯息当中的 SET1 这个字串;
-s  :取代掉重复的字符!

范例一:将 last 输出的讯息中,全部的小写变成大写字符:
$ last  tr '[a-z]' '[A-Z]'
# 事实上,没有加上单引号也是能够执行的,如:“ last | tr [a-z] [A-Z] ”
范例二:将 /etc/passwd 输出的讯息中,将冒号 (:) 删除
$ cat /etc/passwd | tr -d ':'
范例三:将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号删除
$ cp /etc/passwd ~/passwd && unix2dos ~/passwd
$ file /etc/passwd ~/passwd
/etc/passwd:         ASCII text
/home/dmtsai/passwd: ASCII text, with CRLF line terminators  &lt;==就是 DOS 断行
$ cat ~/passwd | tr -d '\r' > ~/passwd.linux
# 那个 \r 指的是 DOS 的断行字符,关于更多的字符,请参考 man tr
$ ll /etc/passwd ~/passwd*
-rw-r--r--. 1 root   root   2092 Jun 17 00:20 /etc/passwd
-rw-r--r--. 1 dmtsai dmtsai 2133 Jul  9 22:13 /home/dmtsai/passwd
-rw-rw-r--. 1 dmtsai dmtsai 2092 Jul  9 22:13 /home/dmtsai/passwd.linux
# 处理事后,发现文件大小与本来的 /etc/passwd 就一致了!

其实这个指令也能够写在“正则表达式”里头!由于他也是由正则表达式的方式来取代数据的! 以上面的例子来讲,使用 [] 能够设置一串字呢!也经常用来取代文件中的怪异符号! 例如上面第三个例子当中,能够去除 DOS 文件留下来的 ^M 这个断行的符号!这东西至关的有用!相信处理 Linux & Windows 系统中的人们最麻烦的一件事就是这个事情啦!亦便是 DOS 下面会自动的在每行行尾加入 ^M 这个断行符号!这个时候除了之前讲过的 dos2unix 以外,咱们也可使用这个 tr 来将 ^M 去除! ^M 可使用 \r 来代替之!

join

join 看字面上的意义 (加入/参加) 就能够知道,他是在处理两个文件之间的数据, 并且,主要是在处理“两个文件当中,有 "相同数据" 的那一行,才将他加在一块儿”的意思。

paste

linux中按列合并文件的命令。相对于 join 必需要比对两个文件的数据相关性, paste 就直接“将两行贴在一块儿,且中间以 [tab] 键隔开”而已!简单的使用方法:

$ paste [-d] file1 file2
选项与参数:
-d  :后面能够接分隔字符。默认是以 [tab] 来分隔的!
-   :若是 file 部分写成 - ,表示来自 standard input 的数据的意思。

expand

将 [tab] 按键转成空白键$ expand [-t] file

选项与参数:
-t  :后面能够接数字。通常来讲,一个 tab 按键能够用 8 个空白键取代。也能够自行定义一个 [tab] 按键表明多少个字符呢!

皮皮blog



分区命令: split

split 能够帮你将一个大文件,依据文件大小或行数来分区,就能够将大文件分区成为小文件了!

在 Linux 下面要将文件分区的话,那么就使用 -b size 来将一个分区的文件限制其大小,若是是行数的话,那么就使用 -l line 来分区!

$ split [-bl] file PREFIX
选项与参数:
-b  :后面可接欲分区成的文件大小,可加单位,例如 b, k, m 等;
-l  :以行数来进行分区。
PREFIX :表明前置字符的意思,可做为分区文件的前导文字。

范例一:个人 /etc/services 有六百多K,若想要分红 300K 一个文件时?
[dmtsai@study ~]$ cd /tmp; split -b 300k /etc/services services
[dmtsai@study tmp]$ ll -k services*
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul  9 22:52 servicesaa
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul  9 22:52 servicesab
-rw-rw-r--. 1 dmtsai dmtsai  55893 Jul  9 22:52 servicesac
# 只要写上前导文字,小文件就会以 xxxaa, xxxab, xxxac 等方式来建立小文件的!

范例二:如何将上面的三个小文件合成一个文件,文件名为 servicesback
[dmtsai@study tmp]$ cat services* >> servicesback
# 用数据流重导向就好

范例三:使用 ls -al / 输出的信息中,每十行记录成一个文件
[dmtsai@study tmp]$ ls -al / &#124; split -l 10 - lsroot
[dmtsai@study tmp]$ wc -l lsroot*
  10 lsrootaa
  10 lsrootab
   4 lsrootac
  24 total
# 重点在那个 - 啦!通常来讲,若是须要 stdout/stdin 时,但恰恰又没有文件,# 有的只是 - 时,那么那个 - 就会被当成 stdin 或 stdout ~


参数代换: xargs

{非管道命令变成管道命令!}

以字面上的意义来看, x 是加减乘除的乘号,args 则是 arguments (参数) 的意思,因此就是在产生某个指令的参数的意思! xargs 能够读入 stdin 的数据,而且以空白字符或断行字符做为分辨,将 stdin 的数据分隔成为 arguments 。 由于是以空白字符做为分隔,因此,若是有一些文件名或者是其余意义的名词内含有空白字符的时候, xargs 可能就会误判了~

-0  :若是输入的 stdin 含有特殊字符,例如 `, \, 空白键等等字符时,这个 -0 参数能够将他还原成通常字符。这个参数能够用于特殊状态喔!If there are blank spaces or characters (including newlines) many commands will not work. This option take cares of file names with blank space.-I (指定了管道前命令做为参数所应该在管道后面命令的位置。e.g. | xargs -I _ mv _ /tmp/c). Replace occurrences of replace-str in the initial-arguments with names read from standard input.  Also, unquoted blanks do not terminate input items; instead the separator is the newline character.$ xargs [-0epn] command
选项与参数:-e  :这个是 EOF (end of file) 的意思。后面能够接一个字串,当 xargs 分析到这个字串时,就会中止继续工做!
-p  :在执行每一个指令的 argument 时,都会询问使用者的意思;
-n  :后面接次数,每次 command 指令执行时,要使用几个参数的意思。-I当 xargs 后面没有接任何的指令时,默认是以 echo 来进行输出!

示例

$ find /usr/sbin -perm /7000 | xargs ls -l

$ find . -name "*.bak" -print0 | xargs -0 -I {} mv {} ~/old.files

出错:xargs: cat: terminated by signal 13

find . \( -name '*.pyc' -o -name '*.py' -type f \) -print | xargs cat

缘由:

[[Linux]若是管道被接受方关闭]

可能的解决:

修改为find . -type f -exec grep "something" {} \; -quit
This is how it works:The -exec will work when the -type f will be true. And because grep returns 0 (success/true) when the -exec grep "something" has a match, the -quit will be triggered.

[bash find xargs grep only single occurence]

皮皮blog


减号 - 的用途

在管线命令当中,经常会使用到前一个指令的 stdout 做为此次的 stdin , 某些指令须要用到文件名称 (例如 tar) 来进行处理时,该 stdin 与 stdout 能够利用减号 "-" 来替代, 举例来讲:

mkdir /tmp/homeback
tar -cvf - /home &#124; tar -xvf - -C /tmp/homeback

上面这个例子是说:“我将 /home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送到 stdout; 通过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - ”。后面的这个 - 则是取用前一个指令的 stdout, 所以,咱们就不须要使用 filename 了!

皮皮blog

from:http://blog.csdn.net/pipisorry/article/details/39760961

ref: 鸟哥的linux私房菜

相关文章
相关标签/搜索