• 主页
  • 归档
  • 分类
  • 照片墙
所有文章 友情链接 关于我

  • 主页
  • 归档
  • 分类
  • 照片墙
  1. 1. 标准输入与管道符
    1. 1.1. 标准输入的重定向
    2. 1.2. 管道符
  2. 2. xargs命令
    1. 2.1. 单独使用
  3. 3. 其他使用技巧
    1. 3.1. 与find的搭配使用
    2. 3.2. -p 和 -t 参数
    3. 3.3. -L 参数

xargs命令

2019-08-23 23:05:33
总字数 1.6k
预计阅读时间 5 分钟

xargs命令的作用可以概括为将标准输入转化为命令行参数

标准输入与管道符

Linux下有些命令是可以接受标准输入的
例如下面这些命令

  • cat 查看文件内容
  • sort 对文件内容的行进行排序
  • uniq 报告或忽略文件中重复的行,必须先进行排序,所以常与sort配合使用
  • grep 根据规则找出匹配到的行
  • wc 获得文件中换行符,字,和字节个数
  • head 输出文件的开头部分
  • tail 输出文件的结尾部分
  • tee 从标准输入读取数据,并同时写到标准输出和文件

标准输入的重定向

我们以sort命令为例
所有可以接受标准输入的默认标准输入指向都是控制台输入
如果直接执行sort
默认标准输入
如果我们把这些内容写到1.txt这个文件当中
就可以执行

1
2
3
sort 1.txt
# 或者
sort < 1.txt

需要注意的是这两种写法虽然效果一样,但是含义是不同的
前者是给sort命令的传参,后者则是输入重定向

查看sort命令的帮助可以看到相关说明
sort help

如果没有指定文件,则从标准输入读取

所以前者并没有改变标准输入的指向,只是因为指定了文件,该命令本身不再从标准输入读取
后者并没有指定文件,而是改变了标准输入的指向

管道符

Linux当中的|称为管道符,使用方式为

1
command1 | command2

它的作用是把command1的标准输出作为command2的标准输入,相当于对command2做了标准输入的重定向
可以利用它完成较为复杂的链式处理
比如

1
tail < 1.log | sort | uniq -d -c | grep 'ab'

表示的含义是

  1. 读取1.log文件的最后10行
  2. 将这10行的内容作为sort的标准输入
  3. 将排序后的内容作为uniq的标准输入,找到其中重复出现的行,以及出现的次数
  4. 重复出现的行内容作为grep的标准输入,从中筛选包含字符串ab行

xargs命令

使用管道符进行链式处理非常方便,但是能够接受标准输入的命令其实很少
大多数命令都不接受,只能接收命令行的传参
比如常见的ls命令,用来查看目录下的文件,它就不接受标准输入
例如现在有apache2和php-apache这两个目录,我们要列出这两个目录里面各自包含的文件
先创建好一个input.txt文件,内容就是

1
apache2 php-apache

命令写法

1
2
3
4
5
6
7
8
9
# 当然可以这样做,常规的传参方式
ls apache2 php-apache

# 如果要从其他来源读取要列出内容的目录呢
ls < input.txt #这样是无效的
cat input.txt | ls #这样与上面的是在做一样的事,同样无效

# 必须使用xargs把标准输出转化为传参
cat input.txt | xargs ls

管道符把标准输出作为xargs的标准输入
xargs则把标准输入转化为了命令行参数,传递给后面真正要执行的命令,在这里就是ls

如果xargs后面没有跟任何命令,那么就代表跟的是echo
echo命令的作用就是把接收到的参数输出到标准输出

单独使用

xargs虽然有这些作用,但是它本身仍然是个可以接受标准输入的命令
如果没有进行标准输入的重定向 (<或者|)
那么它的标准输入就是指向控制台,后面相当于跟着echo
单独执行xargs的表现也就可以理解了

1
2
3
root@ubuntu:~$ xargs
abcd #Ctrl+D
abcd

命令行会等待用户输入,并且把这些输入直接输出

如果跟上了其他命令呢

1
2
3
4
root@ubuntu:~$ xargs find -name
*.txt #Ctrl+D
./input.txt
./1.txt

执行后会等待用户输入,Ctrl+D结束输入
把这些输入的内容作为参数提供给find命令
所以相当于执行find -name *.txt

其他使用技巧

与find的搭配使用

如果我们要删除7天之前修改的文件
由于rm命令只能按照文件名匹配,find则具备多种方式的文件查找
所以两者搭配使用更加方便

先熟悉一下find命令如何按时间查找文件

+nn-n
(n+1)*24H前(n+1)*24H ~ n*24H之间n*24H以内
  • [a|c|m]min [最后访问|最后状态修改|最后内容修改]min(单位是分钟)
  • [a|c|m]time [最后访问|最后状态修改|最后内容修改]time(单位是天)
1
2
# 查找当前目录7天之前修改的文件,并且作为rm的参数执行删除
find ./ -mtime +6 | xargs rm

上面的写法有个问题,就是xargs是使用空白作为参数的分隔的,但是文件名可能包含空格
应该使用下面的写法

1
find ./ -mtime +6 -print0 | xargs -0 rm

-print0提供给find命令,代表输出的文件列表以null作为分隔
-0提供给xargs命令,代表以null作为分隔来切分参数列表

-p 和 -t 参数

过长的命令串联有种难以掌控的感觉,如果出现了失误可能造成无法挽回的结果
-t参数可以在执行xargs后面命令之前打印出要执行的内容
-p参数会等待用户确认,在用户输入y(大小写皆可)后再执行

-L 参数

xargs把标准输入转化为参数提供给后面的命令执行,默认情况下是执行一次的
如果我们要把每一行的输出循环执行呢
这就需要用到-L参数了,后面跟上行数,代表把几行作为一组参数传递给后面的命令执行一次
xargs循环执行

要问带\n的字符串为啥这样写,我只能说shell的晦涩之处不止于此
可以看到前一次执行了ls -l -h
后一次分别执行了ls -l和ls -h

  • linux
  • linux

扫一扫,分享到微信

Web-Workers
洗牌算法 
© 2024 夏夜梦星辰
鲁ICP备19028444号
Power By Hexo
  • 所有文章
  • 友情链接
  • 关于我
{{searchItem.query}}
标签: 分类:
  • maven
  • 持续集成
  • JMS
  • 线程
  • JavaScript
  • ECMAScript6
  • 单元测试
  • Promise
  • Web Worker
  • 函数
  • prototype
  • 模块化
  • 正则表达式
  • 数据库
  • MongoDB
  • 索引
  • 集群
  • 全文检索
  • flutter
  • dart
  • git
  • 版本控制
  • linux
  • shell
  • docker
  • nginx
  • jenkins
  • opencv
  • vim
  • react
  • react native
  • 前端
  • css
  • HTML5
  • Hexo
  • sass
  • Three.js
  • TypeScript
  • Vue
  • 组件化
  • base64
  • webpack
  • nodejs
  • gulp
  • TensorFlow
  • 机器学习
  • 算法
  • 动态规划
  • 数据结构
  • Java
  • JavaScript
  • MongoDB
  • flutter
  • Git
  • linux
  • react
  • 前端杂烩
  • 男生女生
  • 算法
  • 十年饮冰,难凉热血
  • †少女癌†
  • 猫与向日葵
  • coderfun
  • JENKINS
  • API管理后台
愿你最终能接纳每一面每一种的自己
独自活着便是团圆