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