Linux 命令:每日一学,参数传递之xargs命令实践

c6693e64932fc2b252c697d0168c9381.gif

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]

0x01 前言简述

描述:上一章,我们学习了Linux中查找搜寻文件或目录的相关命令,此章我们学习常常与find命令联合使用,以及在Shell脚本中常用的参数替换 xargs 命令进行实践学习,从而实现更加强大的参数传递和多进程并行执行Linux命令或脚本等

原文地址:Linux 命令:每日一学,参数传递之xargs命令实践

Linux 命令 | 系列 文章将作为《#运维从业必学》专栏辅助学习知识,这是也是每位Linux运维工程师必须掌握的基础知识,作者耗费心力、时间进行总结,希望对大家有所帮助,所以若有帮助还请多多关注作者,并鼓励作者创造更多实践文章吧。

好了,还是实践出真知!


0x02 参数替换

xargs 命令 - 将标准输入中的数据转换为命令行参数

描述:xargs(eXtended ARGuments)工具是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。

由于很多命令不支持|管道来传递参数,此时就需要 xargs 命令的帮助,它可以读入stdin 的数据,并将格式化(空格符、回车符进行分隔)后的数据作为命令的参数,还可以将单行或多行文本输入转换为其他格式,例如,多行变单行以及单行变多行,后续实践我们会介绍到。

另外,许多命令不能接受过多的参数而导致命令执行失败,此时可以使用xargs 命令解决该问题。例如,使用 rm 命令删除百万级文件时会提示参数过多,这时可使用 find 命令 或 ls 命令 与 xargs 命令联用进行删除。。

 

工具功能:

将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。

将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。

默认命令是echo 意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。

它能够捕获一个命令的输出,然后传递给另外一个命令,

 

语法参数:

# 用法
command | xargs [OPTION]... COMMAND [INITIAL-ARGS]..

# 常用参数
-0        # 将NULL作为定界符。
-t        # 表示先打印命令,然后再执行。
-a FILE   # 指定一个参数文件,而不是从标准输入中读取。
-n NUM    # 指定每行显示多少NUM列;
-L num    # 从标准输入一次读取 num 行送给 command 命令。 
-l        # 类似于-L,但如果未指定MAX-LINES,则默认为最多一个非空白输入行
-d '定界字符':    # 指定一个定界符注意必须是单字符;
-x, --exit        # 如果超过大小(参见-s),则退出。
-r no-run-if-empty # 当xargs的输入为空的时候则停止xargs,不用再去执行了。
-I R # 指定一个替换字符串{},这个字符串再xargs扩展时会被替换掉,当-I与xargx联合使用的时候每一个参数命令都会被执行一次,类似于find的-ok/-exec选项
-i, --replace[=R] # 看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
-n, --max-args=MAX-ARGS      # 每个命令最多使用MAX-ARGS参数行
-P, --max-procs=MAX-PROCS    # 一次运行最多的max-procs进程
-p, --interactive            # 批量运行命令前交互式提示
-s, --max-chars=MAX-CHARS    # 最多将命令限制为MAX-CHARS
-o, --open-tty # 在执行命令之前,在子进程中将stdin重新打开为/dev/tty;有助于运行
 

使用示例:

首先,定义一个测试用例文件,内有多行文本数据:

$ cat test.txt
a b c d e f 
g h i j k l 
m n o p q r 
s t u v w x y z
 
  • 1.多行输入单行输出和指定行输出

# 示例1.默认情况下的多行变单行处理
cat test.txt | xargs  
  # a b c d e f g h i j k l m n o p q r s t u v w x y z

# 示例2.指定每行显示3个参数
cat test.txt | xargs -n3  
  # a b c 
  # d e f
  # g h i 

# 示例3.指定每行显示4、6个参数
cat test.txt | xargs -n4
cat test.txt | xargs -n6

# 示例4.每次处理 5 个文件,到/backup 目录下
find . -name "*.jpg" | xargs -n 5 cp -t /backup/
ls /backup/
  # 10.jpg  1.jpg  2.jpg  3.jpg  4.jpg  5.jpg  6.jpg  7.jpg  8.jpg  9.jpg

# 示例5.每次处理 10 个文件,移动到/destination 目录下
find /path/to/dir -name "*.jpg" | xargs -n 10 mv -t /destination/示例6.批量添加多个用户到linux中
echo user{1..10} | xargs -n1 useradd
f1963e8d6c8d47ca1a9c02e8fcd9965d.png
weiyigeek.top-指定xargs处理参数后显示的列数
  • 2.指定一个定界符进行分割传递过来的参数字符串

# 默认情况下,xargs 是以换行符,或空格作为分隔符
echo -e "dir1\ndir2\ndir3" | xargs
  # dir1 dir2 dir3

echo "nameXWeiyiGeekXnameX全栈工程师修炼指南" | xargs -dX 
  # name WeiyiGeek name 全栈工程师修炼指南

# 显示成为两列,这是我们需要的格式
echo "nameXWeiyiGeekXnameX全栈工程师修炼指南" |  xargs -dX -n2  
  # name WeiyiGeek
  # name 全栈工程师修炼指南
  • 3.在执行命令之前进行确认,增加安全性:

echo "file1.txt file2.txt file3.txt" | xargs -p rm
  # rm file1.txt file2.txt file3.txt ?...y
  • 4.自定义定义一个占位符,以便在 xargs 中替换特定字符串。

echo "file1 file2 file3" | xargs -I {} mv {} {}.bak

# 示例1.复制所有图片文件到 /data/images/ 目录下,注意反斜杠
mkdir -vp /data/images/
ls *.png *.jpg *.gif | xargs -n1 -I {} cp {} /data/images/

# 示例2.查找当前目录下所有不可修改的文件 (对于入侵监测的时候可使用)
find . | xargs -I {} lsattr -a {} 2>/dev/null | grep '^----i'
  • 5.并行执行命令,提高效率。

# 例1,同时压缩多个文件:
find . -name "*.log" | xargs -P 4 gzip

# 例2, 指定并行进程数为256,批量执行文件上传操作
thread_num=256
ls | xargs -n 1 -I {} -P ${thread_num} sh -c "/usr/binfs_upload_file /etcfs/client.conf {}"
ls -I '*.yml' | xargs -I {} rm -rf {}

# 例3.批量并行执行test.txt文件中,复制文件到到指定目录
cat test.txt <<'EOF'
cp ./0101/123456789.JPG  ../2023/0101/123456789.jpg
cp ./0102/123456789.JPG  ../2023/0102/123456789.jpg
cp ./0103/123456789.JPG  ../2023/0103/123456789.jpg
EOF
cat test.txt | xargs -n 1 -I {} -P 256 sh -c "{}" 

# 例4.并发执行多个进程进行文件下载
seq 100 | xargs -i -P10 wget -P /data http://share.weiyigeek.top/{}.zip

# 例5.并行下载B站视频
yum install python3-pip -y
pip3 install you-getseq 1 100 | xargs -i -P3 you-get https://www.bilibili.com/video/BV19D4y1D7UX?p={}
  • 6.自定义处理空格和特殊字符

# 如果文件名中包含空格或特殊字符,可以使用 -print0 和 -0 选项,让参数以NULL分隔
find . -name "*.log" -print0 | xargs -0
  # ./audit/audit.log ./sssd/sssd_implicit_files.log ./sssd/sssd_nss.log 

# 或者使用 --null 选项,将换行符或空格作为文件名分隔符
find . -type f -name "*.log" -print0 | xargs -n1 --null 
  # ./audit/audit.log ./sssd/sssd_implicit_files.log ./sssd/sssd_nss.log
  • 7.结合 find 命令使用的常规示例。

# 例1.删除某个目录下的所有 .tmp 文件
# 使用用 rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long. 用xargs解决此问题。
find /dir -name "*.tmp" | xargs rm -f

# 例2.查找当前目录下所有 .txt 文件并统计它们的行数:
find . -name "*.txt" | xargs wc -l

# 例3.以 NULL 字符作为换行符,并以三列显示
find . -type f -name "*.log" -print0 | xargs -0 -n3
# ./tuned/tuned.log ./audit/audit.log ./anaconda/anaconda.log
# ./anaconda/X.log ./anaconda/program.log ./anaconda/packaging.log
# ./anaconda/storage.log ./anaconda/ifcfg.log ./anaconda/ks-script-ECgRju.log

# 例4.统计文件信息,统计一个源代码目录中所有php文件的行数
find . -type f -name "*.php" -print0 | xargs -0 wc -l

# 例5,查找当前目录下所有的jpg 文件,并且压缩它们
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz

# 例6. 查询带有 SUID SHID SBIT 等权限的文件
find /bin -perm -7000 | xargs ls -Sl
  • 8.读取stdin将格式化后的参数传递给命令

# 假设一个命令为 weiyigeek.sh 和一个保存参数的文件arg.txt:
# weiyigeek.sh 脚本命令内容,打印出所有参数
tee weiyigeek.sh <<'EOF'
#!/bin/bash 
echo $*  
EOF

# arg.txt 文件内容:
aaa
bbb
ccc

# 可以利用这个来更改ip文本以及脚本参数的传入
cat arg.txt | xargs -I {} ./weiyigeek.sh -p {} -l 
cat arg.txt | xargs -I {} echo $* "-p123" {}"- l123"
-p aaa -l 
-p bbb -l 
-p ccc -l
  • 9.在xargs中,可以使用 $* 获取所有参数, 以此来进行格式化拼接输出。

# 方式1.使用xargs格式化之后输出
cat url.txt | xargs -I {} echo $* "Url:"{}"/admin/web.jsp"

# 也可以使用awk一步搞定,后续我们也要介绍文件处理三剑客之一的命令
awk '{print "Url:"$1"/admin/web.jsp"}' url.txt
# Url:http://demo1.weiyigeek.top/admin/web.jsp
# Url:http://demo2.weiyigeek.top/admin/web.jsp
# Url:http://demo3.weiyigeek.top/admin/web.jsp

a60619f6cad5ddb2b693e60e2217719a.png

weiyigeek.top-使用xargs格式化之后输出
  • 10.将 xargs 与其他命令结合使用,进行更复杂的操作:

# 例1.查找所有 .log 文件中包含 "Error" 的行,并对结果进行排序和去重,最后统计每个唯一行的出现次数
find /path/to/dir -name "*.log" | xargs grep "Error" | sort | uniq -c

# 假2,有一个文件包含了很多你希望下载的URL,你能够使用xargs下载所有链接
cat url-list.txt | xargs -P10 wget -c

原文地址:Linux 命令:每日一学,参数传递之xargs命令实践

若文章写得不错,不要吝惜手中转发,点赞、在看,若有疑问的小伙伴,可在评论区留言你想法哟💬!

温馨提示:作者最近10年的工作学习笔记(涉及网络、安全、运维、开发),需要学习实践笔记的看友,可添加作者账号[WeiyiGeeker],当前价格¥199,除了获得从业笔记的同时还可进行问题答疑以及每月远程技术支持,希望大家多多支持,收获定大于付出!

5bac238defe4f04207af30c9e2954f0a.png


如果此篇文章对你有帮助,请你将它转发给更多的人!

 学习推荐 往期文章

cb953f30f20d4318d1ae9c907fa83f0a.gif

e4b001e6bb34252c0e27fb3ef5544e78.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈工程师修炼指南

原创不易,赞赏鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值