Loading

xargs替代for循环的一种选择

xargs 可以将标准输入转换为给其他命令作为参数。
在命令不支持标准输入,或者我们不想写循环时,这会是一个很有用的命令。

echo "one two three" | xargs mkdir

比如,它会"one two three" 分成3部分,传个mkdir 当参数使用。

这个例子有点多余,毕竟我们可以直接这样

mkdir one two three

我们来用跟多的例子来演示,xargs的参数作用

-d/--delimiter

分隔符,一字符, -d用来控制如何分割。
下面这个命令,会创建一个文件"a-b-c"

$ printf "a-b-c" | xargs touch
$ $ ls a-b-c
a-b-c

默认是以空格为分隔符,如果我们想要创建 a,b,c三个文件,就可以这样,以"-"为分隔符。

$ printf "a-b-c" | xargs -d "-" touch
$ ls a b c
a b c

-n/ --max-args

上面的例子中,看似我们创建了a,b,c三个文件,但是最终的实现是touch a b c这样执行的,我们可以通过参数-t来确认,该参数,会把命令打印输出来

$ printf "a-b-c" | xargs -t -d "-" touch
touch a b c

有的时候,我们运行命令可能不支持多个位置参数的设置,或者有别的需求,需要指定一次传入的参数熟练。这时-n就能实现该目的

$ printf "a-b-c" | xargs -t -n 1 -d "-" touch
touch a
touch b
touch c

-I 参数

上午创建的文件没有文件后缀,如果我们想要加上文件后缀时,该怎么办?

$ printf "a-b-c" | xargs -t -n 1 -I a -d "-" touch 'a.txt'
touch a.txt
touch b.txt
touch c.txt

-I 参数 将指定一个变量名, 后续命令中的该变量名将替换标准输入的值。

-L/--max-lines

我们换一个数据来演示, 下面文件,有9行,每行2个数字,以空格隔开。

$ cat num.txt
1 11
2 22
3 33
4 44
5 55
6 66
7 77
8 88
9 99

对于多行的标准输入,-L/--max-lines, 来控制多少行来作为参数输入

$ cat num.txt | xargs -L 1 echo
1 11
2 22
3 33
4 44
5 55
6 66
7 77
8 88
9 99
$ cat num.txt | xargs -L 2 echo
1 11 2 22
3 33 4 44
5 55 6 66
7 77 8 88
9 99

-P/--max-procs

这个是个非常实用的参数,这个用于控制同一时间运行的最大线程数。想象以下,你有100个2G大小的文件要处理。

for file $(ls data/*.gz);
do
  PROCESS $file
done

如果这样一个一个做,又太慢,不能很好的利用服务器资源,但是如果这样同时挂后台,服务器又顶不住。

for file $(ls data/*.gz);
do
  PROGRAM $file &
done

这时如果用xargs --max-procs , 就能解决这个问题。

ls data/*.gz | xargs --max-procs 20 PROGRAM 

这里就可以每次20个线程的跑了。

多个参数的处理

$ cat num1.txt
1-11
2-22
3-33
4-44
5-55
6-66
7-77
8-88
9-99

对于这个如果我们想要创建 依次创建1/11 这样目录该如何做?

$ cat num1.txt | xargs -d "-" | xargs -n 2 bash -c 'mkdir -p demo/$0/$1'
$ $ tree demo/
demo/
├── 1
│   └── 11
├── 2
│   └── 22
├── 3
│   └── 33
├── 4
│   └── 44
├── 5
│   └── 55
├── 6
│   └── 66
├── 7
│   └── 77
├── 8
│   └── 88
└── 9
    └── 99

18 directories, 0 files

参考

https://ruanyifeng.com/blog/2019/08/xargs-tutorial.html

posted @ 2022-11-20 22:12  何物昂  阅读(201)  评论(0编辑  收藏  举报