xargs使用教程:在实战中学习xargs

前言

xargs命令是获取标准输入来给其他命令传递参数的,
所以xargs一般与管道符(|)一起使用
其作用与管道符(|)类似
但是Linux命令用得多了就有了个疑问:
xargs命令与管道(|)到底有什么区别?
xargs应该怎么用呢?

shell命令加管道(|)的一般形式为(小括号里的xargs表示可选):

echo "hello world" | (xargs) echo

这里我们先作下约定:
管道(”|“)前面的命令(echo "hello world")我们叫它命令A
管道(”|“)后面的命令[(xargs) echo]我们叫它命令B

xargs命令与管道的2点区别

xargs与管道只有2点区别:

区别1:命令B有时候是不接受管道传参的

接受管道传参的命令:catgreplswcawksed

需要说明的是接受管道传参的命令也能用xargs传参,
这个就用到第2点区别了

不接受管道传参的命令:echormkillmkdirtouchcpmv
不接受管道传参的命令一般会报缺少参数的错误:

$ cat test.txt |  touch
touch: missing file operand
Try 'touch --help' for more information.

wedo at slave2 in /opt
$ cat test.txt |  mkdir
mkdir: missing operand
Try 'mkdir --help' for more information.

不接受管道传参的命令一般会报缺少参数的错误

区别2:管道传递参数的是字符串

管道把标准输入用引号引起来,表示1个参数
xargs没有用引号引起来,如果有空格会被识别为多个参数
我们来看一个例子:
命令1:

echo "--help" | cat

命令2:

echo "--help" | xargs cat

看下输出结果:

$ echo "--help" | cat
--help

$ echo "--help" | xargs cat
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s), or standard input, to standard output.

  -A, --show-all           equivalent to -vET
  -b, --number-nonblank    number nonempty output lines, overrides -n
  -e                       equivalent to -vE
  -E, --show-ends          display $ at end of each line
  -n, --number             number all output lines
  -s, --squeeze-blank      suppress repeated empty output lines
  -t                       equivalent to -vT
  -T, --show-tabs          display TAB characters as ^I
  -u                       (ignored)
  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB
      --help     display this help and exit
      --version  output version information and exit
。。。

我们发现命令1中的cat命令相当于执行的是:

cat "--help"

命令2中的cat命令相当于执行的是:

cat --help

那加不加引号又有什么区别呢?
区别大了,你可以想像一下命令A的输出如果有空格会出现什么情况呢?

加引号相当于给命令B传递的只有1个参数,而且只是一个由引号引起的字符串

不加引号,同时命令A的输出结果还有空格,就可能给命令B传递多个参数,

注:
写shell脚本的时候好多时候都最好给命令的参数加个引号,不然万一传递的参数中有空格,就会被识别为多个参数

看下面2个需求:
我们希望查找:以.sh结尾的文件中,包含xargs字符串的文件
我们首先想到的命令是:

find ./ -name "*.sh" | grep "xargs"

输出结果:
输出结果

我们发现这个命令只是找出了当前目录下包含xargs字符串的文件名
这是因为我们find命令的结果,被加了引号后,作为字符串,传给grep去查找,grep实际执行的的其实是:

grep "xargs" "./xargs_demo.sh"

正确的应该是:

find ./ -name "*.sh" | xargs  grep "xargs"

于是我们发现./realtime_import_stop.sh这个文件中有用到xargs命令

$ find ./ -name "*.sh" | xargs  grep "xargs"
./realtime_import_stop.sh:ps aux | grep AppGenerateEverySecond | grep -v "grep" | awk '{print $2}' | xargs kill -s 9

./realtime_import_stop.sh这个文件中有用到xargs命令

换句话说xargs可以通过管道给后面的命令传递多个参数,而且不会被当成字符串

xargs实战

场景1:xargs -i:查找指定格式的文件,并复制到别处

xargs一般是把参数追加到命令的最后,但是如果我想把参数放在命令的中间怎么办呢?于是就有了参数-i

find . -name "*.sh" | xargs -i cp {} /opt/temp

-i参数后可以直接用{}捕获传递的参数
当然你也可以使用-I参数直接将参数赋值给指定变量,下面会讲

这是最常用的使用场景,下面的是不那么常用的,不过也很有用

场景2:xargs -d:指定分隔符

xargs默认以空格分隔参数,如果我希望是其他的分隔符呢?于是就有了参数-d

echo "file1 file2 file3" | xargs echo
echo "file1,file2,file3" | xargs -d "," echo

两个命令意思是一样的:
xargs -d两个命令意思是一样的

哇,能指定分隔符,这不是很有用吗?
你可以执行下下面的命令试试:

echo "file1 file2 file3" | xargs mkdir
echo "file1,file2,file3" | xargs -d "," mkdir

这个时候输出结果就不一样了
xargs -d 输出结果就不一样

为什么会出现这种情况呢?
xargs默认会处理空格,制表符,还有换行,但是你把分隔符指定为逗号,于是它就不处理其他的空白符了

场景3:xargs -t或者-p:命令执行之前先打印下最终要执行的命令

使用参数-t-p
-t不询问,直接执行
-p用户确认(输入y)后执行
可以自己试试下面的命令:

echo "file1,file2,file3" | xargs -d "," -t mkdir
echo "file1,file2,file3" | xargs -d "," -p mkdir

场景4:xargs -n或者-L:我想find 多个匹配

我想同时查找以.sh或以.log结尾的文件怎么办呢?
方法1:

echo "*.sh *.log" | xargs -n 1 find . -name

-n:参数的意思为每次传递多少个参数给命令B执行,
-n 1:意为xargs接收标准输入后按空格分成了2个参数,但是一次只给命令B传1个

方法2

echo "*.sh\n*.log" | xargs -L 1 find . -name

-L参数的意思为每次传递多少行参数给命令B执行
-L 1意为xargs接收标准输入后把 参数分隔成了2行,1行1个参数,一次给命令B传1行参数

场景5:xargs -I:给参数赋值给变量

-I参数可以把值赋给变量
这个场景更加不常用,
也不是说不常用,因为一般能用这个参实现的用-i都能实现
不过可以试试下面的命令:

echo "file1 file2 file3" | xargs -I var sh -c "echo var; touch var"

该命令意为将标准输入传递的值赋值给变量var
然后先打印变量值,再创建文件
一般来说-I都使用-i参数搞定,

echo "file1 file2 file3" | xargs -i sh -c "echo {}; touch {}"

两个命令意思是一样的

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值