• 管道指令如何配合mv进行特殊文件的批量剪切


     本次任务:将某一目录下所有的显式文件(不包括文件夹)全部移到指定目录下。

    情景:

    • 在root的home目录(~或/root)下有这些文件和目录(文件夹)

    [root@localhost ~]# ll
    total 132
    -rw-------.  1 root root  2596 Apr 18 17:00 anaconda-ks.cfg
    -rw-r--r--.  1 root root   392 Jun  2 21:54 another
    -rw-r--r--.  1 root root   176 Sep 15  2007 bashrc
    -rw-r--r--.  1 root root    22 Jun  7 15:57 catfile
    -rw-r--r--.  1 root root  2872 Jun  7 18:37 col.man
    -rw-r--r--.  1 root root    50 Jun  2 21:55 fiveten
    drwxr-xr-x.  3 root root  4096 Apr 18 17:00 home
    -rw-r--r--.  1 root root  1167 Jun  7 18:20 homefile
    drwxr-xr-x. 22 root root  4096 Jun  2 19:23 initrd
    -rw-r--r--.  1 root root 45509 Apr 18 17:00 install.log
    -rw-r--r--.  1 root root 13217 Apr 18 16:59 install.log.syslog
    -rw-r--r--.  1 root root  7122 Jun  7 18:17 last.list
    -rw-r--r--.  1 root root    89 Jun  9 23:14 pay.txt
    -rw-r--r--.  1 root root    97 Jun  9 21:14 printf.txt
    -rw-r--r--.  1 root root   650 Jun  9 20:56 regular_express.txt
    -rw-r--r--.  1 root root  1167 Jun  7 15:35 rootfile
    drwxr-xr-x.  2 root root  4096 Jun 14 10:54 test

    • 由上面的输出可知,home,initrd,test为目录,我们要将所有除目录外的显示文件都剪切到test目录下。

    方法一:

    ll | grep '^-' | awk '{print $9}' | xargs -i mv {} ./test

    分析:

    ll(ls -l):列出当前目录下显式的文件和目录的详细信息。共有九个字段,其中第一个字段表示文档的属性,-:表示普通文件,d:表示目录文件。

    |:竖线,Enter键上面的那个按键,该符号为管道,作用是管道符左边命令的输出就会作为管道符右边命令的输入。

    grep '^-':提取出开头字符为‘-’的输出行。也即提取出显式普通文件,去掉目录,‘^word’表示待搜寻的字符串(word)在行首,grep按行为单位进行操作。

    awk '{print $9}':该命令提取出文件的名称,通常在第九列。awk主要处理每一行的字段内的数据,默认的字段分隔符为空格键或TAB键可能导致提取错误)。而sed主要以行为单位处理数据。awk后面接两个单引号并加上大括号 {} 来设定想要对数据进行的处理动作,并且透过 print 的功能将字段数据列出来。

    xargs -i mv {} ./test:将上一个命令输出的文件名构造成参数列表,传递给mv指令使用。至此所有的除目录外的文件都剪切到test/目录中了

    xargs的用法之一是构造参数列表并运行命令,即将接收的参数传递给后面的command 命令执行由于mv,ls,cp不支持管道命令,所以可以配合xargs使用,达到相同的效果。-i -i 选项告诉 xargs 可以使用{}代替传递过来的参数, 建议使用-I(是i的大写字母I,不是数字1,也不是L的小写字母),其符合POSIX标准,由于mv的第一个参数为源文件,在这里{}的作用就是表示xargs处理后的参数传递到{}中供mv使用。所以也可写成:

    [root@localhost ~]# ll | grep '^-' | awk '{print $9}' | xargs -I {} mv {} ./test 


    [root@localhost ~]# man xargs

    -I replace-str
                  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.  Implies -x and -L 1.


    执行结果如下:

    [root@localhost ~]# ll | grep '^-' | awk '{print $9}' | xargs -i mv {} ./test
    [root@localhost ~]# ls
    home  initrd  test
    [root@localhost ~]# cd test
    [root@localhost test]# ls
    anaconda-ks.cfg  catfile  homefile            last.list   regular_express.txt
    another          col.man  install.log         pay.txt     rootfile
    bashrc           fiveten  install.log.syslog  printf.txt

    [root@localhost test]# ll
    total 120
    -rw-------. 1 root root  2596 Apr 18 17:00 anaconda-ks.cfg
    -rw-r--r--. 1 root root   392 Jun  2 21:54 another
    -rw-r--r--. 1 root root   176 Sep 15  2007 bashrc
    -rw-r--r--. 1 root root    22 Jun  7 15:57 catfile
    -rw-r--r--. 1 root root  2872 Jun  7 18:37 col.man
    -rw-r--r--. 1 root root    50 Jun  2 21:55 fiveten
    -rw-r--r--. 1 root root  1167 Jun  7 18:20 homefile
    -rw-r--r--. 1 root root 45509 Apr 18 17:00 install.log
    -rw-r--r--. 1 root root 13217 Apr 18 16:59 install.log.syslog
    -rw-r--r--. 1 root root  7122 Jun  7 18:17 last.list
    -rw-r--r--. 1 root root    89 Jun  9 23:14 pay.txt
    -rw-r--r--. 1 root root    97 Jun  9 21:14 printf.txt
    -rw-r--r--. 1 root root   650 Jun  9 20:56 regular_express.txt
    -rw-r--r--. 1 root root  1167 Jun  7 15:35 rootfile
    [root@localhost test]# cd ..
    [root@localhost ~]# ll
    total 12
    drwxr-xr-x.  3 root root 4096 Apr 18 17:00 home
    drwxr-xr-x. 22 root root 4096 Jun  2 19:23 initrd
    drwxr-xr-x.  2 root root 4096 Jun 14 11:43 test

    由上看到所有的除目录外的文件都移到test/目录下,如此看来功能都实现了,但是……

    当文档名称中间有空格怎么办呢,由于awk命令的“缺陷”:默认以空格或TAB键为空格,会产生误判,

    举例:

    [root@localhost ~]# touch "f ile"
    [root@localhost ~]# ls
    anaconda-ks.cfg  col.man  homefile            last.list            rootfile
    another          f ile    initrd              pay.txt              test
    bashrc           fiveten  install.log         printf.txt

    catfile          home     install.log.syslog  regular_express.txt

    [root@localhost ~]# ll | grep '^-' | awk '{print $9}' | xargs -I {} mv {} ./test
    mv: cannot stat `f': No such file or directory
    [root@localhost ~]# ls
    f ile  home  initrd  test

    出现错误了,“f ile”文件没有被剪切过去。

    解决方法:

    ls -1 -F | grep -v [/$] | xargs -I {} mv {} ./test

    解释:

    ls -1 ,注意这里是数字1,作用是单列输出。-1     list one file per line

    ls-F:根据文件、目录等信息在文件名或目录名最后给予附加数据结构,例如:

    *代表可执行文件;/代表目录;=代表socket文件;|代表FIFO文件;@代表连接文件

    -F, --classify
                  append indicator (one of */=>@|) to entries


    [root@localhost ~]# ls -1
    f ile
    home
    initrd
    test
    [root@localhost ~]# ls -F
    f ile  home/  initrd/  test/
    [root@localhost ~]#

    通过上面的一个任务熟悉了linux下管线,正规表达式,通配符,bash命令等的使用。


    通配符和正规表达式的区别?

  • 相关阅读:
    CodeSmith实用技巧(十四):使用Progress对象
    .NET设计模式(5):工厂方法模式(Factory Method)
    CodeSmith实用技巧(七):从父模版拷贝属性
    CodeSmith实用技巧(十一):添加设计器的支持
    CodeSmith实用技巧(六):使用XML 属性
    CodeSmith实用技巧(三):使用FileDialogAttribute
    CodeSmith实用技巧(十二):自动执行SQL脚本
    CodeSmith中实现选择表字段的几点想法
    CodeSmith开发系列资料总结
    你真的了解.NET中的String吗?
  • 原文地址:https://www.cnblogs.com/cnsec/p/3789790.html
Copyright © 2020-2023  润新知