前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Linux 命令:每日一学,参数传递之xargs命令实践

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

作者头像
全栈工程师修炼指南
发布2024-10-11 18:45:42
发布2024-10-11 18:45:42
41000
代码可运行
举报
运行总次数:0
代码可运行

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

0x01 前言简述

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


0x02 参数替换

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

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

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

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

工具功能:

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

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

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

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

语法参数:

代码语言:javascript
代码运行次数:0
复制
# 用法
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;有助于运行

使用示例:

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

代码语言:javascript
代码运行次数:0
复制
$ 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.多行输入单行输出和指定行输出
代码语言:javascript
代码运行次数:0
复制
# 示例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

weiyigeek.top-指定xargs处理参数后显示的列数

  • 2.指定一个定界符进行分割传递过来的参数字符串
代码语言:javascript
代码运行次数:0
复制
# 默认情况下,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.在执行命令之前进行确认,增加安全性:
代码语言:javascript
代码运行次数:0
复制
echo "file1.txt file2.txt file3.txt" | xargs -p rm
  # rm file1.txt file2.txt file3.txt ?...y
  • 4.自定义定义一个占位符,以便在 xargs 中替换特定字符串。
代码语言:javascript
代码运行次数:0
复制
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.并行执行命令,提高效率。
代码语言:javascript
代码运行次数:0
复制
# 例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.自定义处理空格和特殊字符
代码语言:javascript
代码运行次数:0
复制
# 如果文件名中包含空格或特殊字符,可以使用 -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 命令使用的常规示例。
代码语言:javascript
代码运行次数:0
复制
# 例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将格式化后的参数传递给命令
代码语言:javascript
代码运行次数:0
复制
# 假设一个命令为 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中,可以使用 $* 获取所有参数, 以此来进行格式化拼接输出。
代码语言:javascript
代码运行次数:0
复制
# 方式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

weiyigeek.top-使用xargs格式化之后输出

  • 10.将 xargs 与其他命令结合使用,进行更复杂的操作:
代码语言:javascript
代码运行次数:0
复制
# 例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 
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈工程师修炼指南 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 前言简述
  • 0x02 参数替换
    • xargs 命令 - 将标准输入中的数据转换为命令行参数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档