【转】linux中的cut/tr/join/split/xargs命令

1. cut命令

cut命令用于从文件或者标准输入中读取内容并截取每一行的特定部分并送到标准输出。

截取的方式有三种:
一是按照字符位置,二是按照字节位置,
三是使用一个分隔符将一行分割成多个field,并提取指定的fields。

cut命令有5个参数,其中-c,-b,-f分别表示"character", "byte"以及"field"截取方式。
当采用field模式截取时,需要用"-d"参数指定一个分隔符,分割符只能为单个字符。另外还有一个"-s",suppress,表示如果行中没有给出的分割符则不输出该行(默认为如果没有分隔符则将该行原封不动输出)

以下为几个例子:

按字符截取:echo hello, world | cut -c 8-12 则输出"world"(截取字符串中从第8到第12个共12个字符)
按分隔符截取:echo hello, world | cut -f 2 -d " "则输出"world"(截取以空格分割的第二部分)
echo Long, long ago | cut -f 2,3 -d " "则输出" long ago"(截取以空格分割的第2、3部分,注意输出的结果也以-d指定的分隔符分割)
使用"-s"安静地忽略没有给出地分隔符地行:echo hello |cut -d "!" -f 1 -s则什么也不输出(因为行中没有"!"字符)
如果命令执行成功则返回0,遇到错误则返回一个大于0的数字。

其中-c,-b,好理解,下面我自己理解的-f参数,自己多试验几次,多输出几次,就明白了。

    # echo Long,long ago,ddddddd | cut -f 2 -d ,
    long ago

    # echo Long,long ago,ddddddd | cut -f 2- -d ,
    long ago,ddddddd

    # echo Long,long ago,ddddddd,hhhhhhhhhhh | cut -f 2- -d ,
    long ago,ddddddd,hhhhhhhhhhh

 上面三个对比一下就会很清楚。

# echo Long,long ago,ddddddd | cut -f 2,3 -d ,
long ago,ddddddd
# echo Long,long ago,ddddddd | cut -f 1,3 -d ,
Long,ddddddd
# echo Long,long ago,ddddddd | cut -f 1,2 -d ,
Long,long ago
# echo Long,long ago ddddddd | cut -f 2 -d ,
long ago ddddddd

# echo Long,long ago ddddddd | cut -f 2,3 -d ,
long ago ddddddd

2. tr命令

     通过使用 tr,您可以非常容易地实现 sed 的许多最基本功能。您可以将 tr 看作为 sed 的(极其)简化的变体:它可以用一个字符来替换另一个字符,或者可以完全除去一些字符。您也可以用它来除去重复字符。这就是所有 tr 所能够做的。     
     tr用来从标准输入中通过替换或删除操作进行字符转换。tr主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串1用于查 询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。
   带有最常用选项的tr命令格式为:

tr -c -d -s ["string1_to_translate_from"] ["string2_to_translate_to"] < input-file

 这里:
-c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
input-file是转换文件名。虽然可以使用其他格式输入,但这种格式最常用。

指定字符串1或字符串2的内容时,只能使用单字符或字符串范围或列表。
[a-z] a-z内的字符组成的字符串。
[A-Z] A-Z内的字符组成的字符串。
[0-9] 数字串。
\octal 一个三位的八进制数,对应有效的ASCII字符。
[O*n] 表示字符O重复出现指定次数n。因此[O*2]匹配OO的字符串。
tr中特定控制字符的不同表达方式
速记符含义八进制方式
\a Ctrl-G  铃声\007
\b Ctrl-H  退格符\010
\f Ctrl-L  走行换页\014
\n Ctrl-J  新行\012
\r Ctrl-M  回车\015
\t Ctrl-I  tab键\011
\v Ctrl-X  \030

实例:

 将文件file中出现的"abc"替换为"xyz"
 # cat file | tr "abc" "xyz" > new_file
 【注意】这里,凡是在file中出现的"a"字母,都替换成"x"字母,"b"字母替换为"y"字母,"c"字母替换为"z"字母。而不是将字符串"abc"替换为字符串"xyz"。

使用tr命令“统一”字母大小写
(小写 --> 大写)
# cat file | tr [a-z] [A-Z] > new_file
(大写 --> 小写)
# cat file | tr [A-Z] [a-z] > new_file

把文件中的数字0-9替换为a-j
 # cat file | tr [0-9] [a-j] > new_file

删除文件file中出现的"Snail"字符
 # cat file | tr -d "Snail" > new_file
 【注意】这里,凡是在file文件中出现的'S','n','a','i','l'字符都会被删除!而不是紧紧删除出现的"Snail”字符串。

删除文件file中出现的换行'\n'、制表'\t'字符
 # cat file | tr -d "\n\t" > new_file
 不可见字符都得用转义字符来表示的,这个都是统一的。

删除“连续着的”重复字母,只保留第一个
 # cat file | tr -s [a-zA-Z] > new_file

删除空行
 # cat file | tr -s "\n" > new_file

删除Windows文件“造成”的'^M'字符
 # cat file | tr -d "\r" > new_file
 【注意】这里-s后面是两个参数"\r"和"\n",用后者替换前者

用空格符\040替换制表符\011
 # cat file | tr -s "\011" "\040" > new_file

把路径变量中的冒号":",替换成换行符"\n"
 # echo $PATH | tr -s ":" "\n"

3. join命令

join命令
   功能:“将两个文件中指定栏位相同的行连接起来”,即按照两个文件中共同拥有的某一列,将对应的行拼接成一行。
 join [options] file1 file2
     注:这两个文件必须在已经在此列上是按照相同的规则进行了排序。
join选项
   -a FILENUM:除了显示匹配好的行另外将指定序号(1或2)文件中部匹配的行显示出来
   -e EMPTY:将需要显示但是文件中不存在的域用此选项指定的字符代替
   -i :忽略大小写
   -j FIELD :等同于 -1 FIELD -2 FIELD,-j指定一个域作为匹配字段
   -o FORMAT:以指定格式输出
   -t CHAR :以指定字符作为输入输出的分隔符
          join 默认以空白字符做分隔符(空格和\t),可以使用 join -t $'\t'来指定使用tab做分隔符
   -v FILENUM:与-a相似 但值显示文件中没匹配上的行
   -1 FIELD:以file1中FIELD字段进行匹配
   -2 FIELD:以file2中FIELD字段进行匹配
   --help :打印命令帮助文件
例子:
文件 file1.txt
    aa 1 2
    bb 2 3
    cc 4 6
    dd 3 3
文件file2.txt

    aa 2 1
    bb 8 2
    ff 2 4
    cc 4 4
    dd 5 5

1.join file1.txt file2.txt
 输出:aa 1 2 2 1
       bb 2 3 8 2
  默认已两个文件的第一行做匹配字段,默认以空格(不限个数)做分隔符。
2.join -j 1 file1.txt file2.txt
输出:aa 1 2 2 1
      bb 2 3 8 9
 -j选项 指定了以两个文件中第一列做匹配字段 等同于join file1.txt file2.txt
3. join -1 2 -2 3 file1.txt file2.txt
输出: 1 aa 2 aa 2
     2 bb 3 bb 8
     4 cc 6 ff 2
     4 cc 6 cc 4
 以第一个文件的第二列和第二个文件的第三列做匹配字段。由于第二个文件中第三列的两个3 都与第一个文件中第三行因此输出
    4 cc 6 ff 2
    4 cc 6 cc 4
4 join -o 1.1 -o 1.2  -o 1.3 -o 2.1 -o 2.2 -o 2.3   -e 'empty' -a 1  file1.txt file2.txt 
输出: aa 1 2 aa 2 1
       bb 2 3 bb 8 2
    cc 4 6 empty empty empty
    dd 3 3 empty empty empty
 -o 指定 将file1的1,2,3列,file2的1,2,3 列都输出。-a指定将file1中不匹配的行也输出,但是file2中没有与file1后两行对应的字段,因此使用empty补齐。

5.join  -v 1  file1.txt file2.txt 
  输出: cc 4 6
         dd 3 3
 -v 1 将file1中不匹配的行输出
PS:join命令和数据库中的join命令很类似。
    虽然file1和file2都已经排序,但是由于在第三行时开始不匹配因此只匹配上了前两行,后面的行虽然字段也可以对应但是以不能匹配。join命令,对文件格式的要求非常强,如果想要更灵活的使用,可用AWK命令,参加AWK实例

6. join 标准输入
  有时我们需要将多个格式相同的文件join到一起,而join接受的是两个文件的指令,此时我们可以使用管道和字符“-"来实现
    join file1 file2 | join - file3 | join - file4 
  这样就可以将四个文件 连接到 一起了。 

4. split命令

否想要把一个大文件分割成多个小文件?比如一个5gb日志文件,我们需要把它分成多个小文件,这样我们才有可能使用普通的文本编辑器读取 它。有时我们需要传输20gb的大文件到另一台服务器,这就需要我们把它分割成多个文件,这样便于传输数据。下面我们来通过五个实例来讲解它。
 
实例1、以每个文件1000行分割
split命令分割文件成每个文件1000行,并且文件名依次为 [前缀]aa, [前缀]ab, [前缀]ac等,默认的前缀是X,每个文件的行数为1000行,命令如下:
$ split mylog
$ wc -l *
4450 mylog
1000 xaa
1000 xab
1000 xac
1000 xad
450 xae

 

实例2、以每个文件20MB分割

分割文件为多个20MB的文件,附带-b选项命令如下:

    $ split -b 20M logdata
    $ ls -lh | tail -n +2
    -rw------- 1 sathiya sathiya 102M Jul 25 18:47 logdata
    -rw------- 1 sathiya sathiya  20M Jul 25 19:20 xaa
    -rw------- 1 sathiya sathiya  20M Jul 25 19:20 xab
    -rw------- 1 sathiya sathiya  20M Jul 25 19:20 xac
    -rw------- 1 sathiya sathiya  20M Jul 25 19:20 xad

 

实例3、以每个文件50MB指定前缀分割

使用–bytes选项把文件分割成多个50MB的文件,–bytes类似-b选项,在第二个参数指定前缀。

    $ split --bytes=50M logdata mydatafile
    $ ls -lh
    total 204M
    -rw------- 1 sathiya sathiya 102M Jul 25 18:47 logdata
    -rw------- 1 sathiya sathiya  50M Jul 25 19:23 mydatafileaa

 

实例4、基于行数分割文件

使用-l选项指定行数来把文件分割成多个行数相同的文件。

    $ wc -l testfile
    2591 testfile
    $ split -l 1500 testfile importantlog
    $ wc -l *
    1500 importantlogaa
    1091 importantlogab
    2591 testfile

 

实例5、以数字后缀命名分割文件

使用-d选项可以指定后缀为数字,如00,01,02..,而不是aa,ab,ac。

    $ split -d testfile
    $ ls
    testfile  x00  x01  x02
可用选项

短 选项长选项选项描述-b–bytes=SIZESIZE 值为每一输出档案的大小,单位为 byte。-C–line-bytes=SIZE每一输出档中,单行的最大 byte 数。-d–numeric-suffixes使用数字作为后缀。-l–lines=NUMBERNUMBER 值为每一输出档的列数大小。

测试的时候发现-b 选项老提示出错,没查什么原因,改成--bytes=20000000 了

另外可以复合使用这些选项   比如

split -d --bytes=20000000 testfile aaa_

这样出来的文件是

aaa_00,aaa_01,…… aaa_...


5. xargs命令

xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理。通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从文件的输出中读取数据。xargs的默认命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。

xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令,下面是一些如何有效使用xargs 的实用例子。

1. 当你尝试用rm 删除太多的文件,你可能得到一个错误信息:/bin/rm Argument list too long. 用xargs 去避免这个问题
find ~ -name ‘*.log’ -print0 | xargs -0 rm -f
 

2. 获得/etc/ 下所有*.conf 结尾的文件列表,有几种不同的方法能得到相同的结果,下面的例子仅仅是示范怎么实用xargs ,在这个例子中实用 xargs将find 命令的输出传递给ls -l
# find /etc -name "*.conf" | xargs ls –l

3. 假如你有一个文件包含了很多你希望下载的URL, 你能够使用xargs 下载所有链接
# cat url-list.txt | xargs wget –c
 
4. 查找所有的jpg 文件,并且压缩它
# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz

5. 拷贝所有的图片文件到一个外部的硬盘驱动 
# ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory

 

posted @ 2013-11-07 16:54  myLittleGarden  阅读(1237)  评论(0编辑  收藏  举报