xargs 给其他命令传递参数的一个过滤器
Linux那点事-xargs命令详解 困惑点解答
xargs 命令教程
xargs命令详解,xargs与管道的区别
linux xargs 命令详解
xargs原理剖析及用法详解
linux中xargs命令的使用方式
xargs
命令的作用,是将标准输入转为命令行参数。
$ echo "hello world" | xargs echo hello world
上面的代码将管道左侧的标准输入,转为命令行参数hello world
,传给第二个echo
命令。
xargs
命令的格式如下。
$ xargs [-options] [command]
真正执行的命令,紧跟在xargs
后面,接受xargs
传来的参数。
xargs
的作用在于,大多数命令(比如rm
、mkdir
、ls
)与管道一起使用时,都需要xargs
将标准输入转为命令行参数。
$ echo "one two three" | xargs mkdir
上面的代码等同于mkdir one two three
。如果不加xargs
就会报错,提示mkdir
缺少操作参数。
参数 | 参数解释 | |
---|---|---|
xargs处理的优先级或顺序 | 先分割,在分批,然后传递到参数位 | |
分割 | 默认情况下,xargs使用空格来切分数据。 | |
-d | xargs -d可以指定分割符,可以是单个符号、字母或者数字。如指定o 为分割符:xargs -d "o" ; |
|
-0 (等同于 --null) | 和xargs -d 基本一样,只是-d 是指定分割符,-0 是指定固定的\0 作为分割符。等价于xargs -d "\0" 。 |
|
分批行为 | 指定一次获取多少数量的数据 | |
-n | 按空格分段划批的,若有 10 个数据, -n 2,就是每次获取 2 个,因此会执行 5 次 | |
-L | 按段划批 | |
-i、-L、-n 选项都是分批选项,他们的生效规则是:谁指定在后面,谁就生效 |
||
指定参数位置 | 接收传来的数据 | |
-i | -i 默认使用大括号作为替换符号 |
|
-I(大写i) | -I 可以指定其他符号、字母、数字作为替换符号,但是必须用引号 包起来(好像不用引号也行) |
|
观察命令的执行过程 | ||
-p | -p 选项是交互询问式的,只有每次询问的时候输入y(或者yes) 才会执行,直接按entry 键是不会执行的 |
|
-t | -t 选项是在每次执行xargs 后面的命令都会先在stderr 上打印一遍命令的执行过程然后才正式执行 |
|
并发处理 | ||
- P | xargs提供 了-P 选项,用于指定并发执行的数量(默认是只要一个处理进程,不会提供效率,但是可以指定为N个子进程,或者指定为0表示尽可能多的利用 CPU )。这样就能将让分批操作更好的利用多核CPU,从而提升效率。例如上面分成了两批,指定 -P 2 可以并发执行两批,而并非执行完第一批之后再执行第二批 |
|
-d 参数与分隔符 | $ echo -e “a\tb\tc” | xargs -d “\t” echo a b c |
Mandatory arguments to long options are mandatory for short options too.
Non-mandatory arguments are indicated by [square brackets]
-0, --null Items are separated by a null, not whitespace.
Disables quote and backslash processing
-a, --arg-file=FILE Read arguments from FILE, not standard input
-d, --delimiter=CHARACTER Input items are separated by CHARACTER, not by
blank space. Disables quote and backslash
processing
-E END If END occurs as a line of input, the rest of
the input is ignored.
-e [END], --eof[=END] Equivalent to -E END if END is specified.
Otherwise, there is no end-of-file string
--help Print a summary of the options to xargs.
-I R same as --replace=R (R must be specified)
-i,--replace=[R] Replace R in initial arguments with names
read from standard input. If R is
unspecified, assume {}
-L,-l, --max-lines=MAX-LINES Use at most MAX-LINES nonblank input lines per
command line
-l Use at most one nonblank input line per
command line
-n, --max-args=MAX-ARGS Use at most MAX-ARGS arguments per command
line
-P, --max-procs=MAX-PROCS Run up to max-procs processes at a time
-p, --interactive Prompt before running commands
--process-slot-var=VAR Set environment variable VAR in child
processes
-r, --no-run-if-empty If there are no arguments, run no command.
If this option is not given, COMMAND will be
run at least once.
-s, --max-chars=MAX-CHARS Limit commands to MAX-CHARS at most
--show-limits Show limits on command-line length.
-t, --verbose Print commands before executing them
--version Print the version number
-x, --exit Exit if the size (see -s) is exceeded
# 初始内容
$ ls
bin downloads env go versions
# 了解 -,最后指定 - 则表示从标准输入中读取
$ echo 'main' | cat -
main
# 用 - 承接 ls 传递的信息,发现无法打印,暂不清楚原因(可能 echo 无法承接这么多参数)
$ ls | echo -
# xargs 可以打印,相当于 将 ls 的输出,作为输入参数,传递给 echo 进行打印
$ ls | xargs echo
bin downloads env go versions
# xargs -n 相当于将 ls 传递的信息进行分割后,指定每次传输的数量
$ ls | xargs -n 1 echo
bin
downloads
env
go
versions
# 初始内容
$ ls
bin downloads env go versions
# 我们想打印的格式为 xx is a dir
# 但是 xargs 传递的参数,默认会填充到最后,因此不满足要求
$ ls | xargs -n 1 echo "is a dir"
is a dir bin
is a dir downloads
is a dir env
is a dir go
is a dir versions
# 通过 -I 参数,指定可以替换的标志为 {}, 之后的 {} 将会替换 xargs 传来的内容,满足要求
$ ls | xargs -n 1 -I {} echo {} "is a dir"
bin is a dir
downloads is a dir
env is a dir
go is a dir
versions is a dir
# xargs 默认就带打印,可以理解为 xargs echo
$ echo "nameXnameXnameXname" | xargs
nameXnameXnameXname
# -d 制定分割符为 X
$ echo "nameXnameXnameXname" | xargs -d X
name name name name
# -n 指定,每次传输多少个数据
$ echo "nameXnameXnameXname" | xargs -d X -n 2
name name
# 带双引号,也可以分割
$ echo '11@22@33' | xargs -d '@' echo
11 22 33
# 不带双引号,也可以
$ echo '11@22@33' | xargs -d @ echo
11 22 33
$ echo -e "a\nb\nc" | xargs -L 1 echo
a
b
c
$ echo -e "a\nb\nc" | xargs -L 2 echo
a b
c
# 这里有三个镜像
$ ls
calico-0.45.tar calico-bird.tar calico-bpftool.tar
# docker load -i 只能每次导入一个 镜像
# 这里通过 xargs 实现导入 3个镜像
$ ls | xargs -n 1 -I {} docker load -i {}
由于xargs
默认将空格作为分隔符,所以不太适合处理文件名,因为文件名可能包含空格。
find
命令有一个特别的参数-print0
,指定输出的文件列表以null
分隔。然后,xargs
命令的-0
参数表示用null
当作分隔符。
删除/log
路径下的所有文件。由于分隔符是null
,所以处理包含空格的文件名,也不会报错。
还有一个原因,使得xargs
特别适合find
命令。有些命令(比如rm
)一旦参数过多会报错"参数列表过长",而无法执行,改用xargs
就没有这个问题,因为它可以指定执行的参数的个数
# 创建实例文件 $ mkdir log $ touch 1.log 2.log # -print 0 作用,是文件已 null 分隔开 # -t 是显示执行的命令,此处可以看到是 一条命令执行删除所有文件 # --null 是指定 null 为分隔符,此处也可以用 -0 $ find log/ -type f -print0|xargs -t --null rm rm log/1.log log/2.log # 假如要删除的文件是 1000 个,可能就会报 参数过长 错误 # 因此可以使用 -n 指定一次处理的个数,如 此处一次处理一个文件 $ find log/ -type f -print0|xargs -t --null -n 1 rm rm log/1.log rm log/2.log
找出所有 TXT 文件以后,对每个文件搜索一次是否包含字符串abc
。
$ find . -name "*.txt" | xargs grep "abc"
xargs通常与find命令结合使用。您可以使用find搜索特定文件,然后使用xargs对这些文件执行操作。
若要避免包含换行符或其他特殊字符的文件名出现问题,请始终使用find的-print0选项,这样可以使find打印完整的文件名,配合xargs命令使用-0或者–null选项可以正确的解释。
下面例子中,查找log文件夹下面的类型为file的所有文件,打包压缩起来:
$ find log/ -type f -print0|xargs -t --null tar -zcvf logs.tar.gz
tar -zcvf logs.tar.gz log/1.log log/2.log
log/1.log
log/2.log