玩转xargs

Unix命令可以从标准输入(stdin)或命令行参数中接受数据。利用管道可以将一个命令的标准输出传入到另一个命令的标准输入

可以用别的方法来调用只能接受命令行参数的命令,最简单的方法就是使用反引号执行命令,然后将其输出作为命令行参数

$ gcc `find '*.c'`

这种方法在很多情况下都管用,但是如果要处理的文件过多,则会出现Argument list too long。xrag命令可以解决这个问题
xargs命令从stdin处读取一系列参数,然后使用这些参数来执行指定命令。能将单行或多行输入文本转换成其它格式,例如单行变多行或多行变单行

1. 预备知识

xargs命令应该紧跟在管道操作符之后。它使用标准输入作为主要的数据源,将从stdin中读取的数据作为指定命令的参数并执行该命令

ls *.c | xargs grep main # 在一组C语言源代码文件中搜索字符串main

xargs命令重新格式化stdin接收到的数据,再将其作为参数提供给指定命令。xargs默认会执行echo命令。和find命令的-exec选项相比,两者在很多方面都很相似

# 1. 将多行输入转换成单行输出
$ cat example.txt
1   2   3   4   5   6
7   8   9   10
11  12$ cat example.txt| xargs
1   2   3   4   5   6   7   8   9   10  11  12
# 2. 将单行输入转换成多行输出
## -n选项可以限制每次调用命令时用到的参数个数
$ cat example.txt| xargs -n 3
1   2   3
4   5   6
7   8   9
10  11  12

2.工作原理

xargs命令接受来自stdin的输入,将数据解析成单个元素,然后调用指定命令并将这些元素作为该命令的参数。xargs默认使用空白字符分隔输入并执行/bin/echo
可以定义一个用来分隔参数的分隔符。-d选项可以为输入数据指定自定义的分隔符

$ echo "splitXsplit2Xsplit3Xsplit4"| xargs -d X
split1  split2  split3  split4# 结合-n选项,可以将输入分割成多行,每行包含两个单词
$ echo "splitXsplit2Xsplit3Xsplit4"| xargs -d X -n 2
split1  split2
split3  split4

xargs命令可以和find命令很好地结合在一起,find地输出可以通过管道传给xargs,然后再由xargs执行-exec选项所无法处理的复杂操作。如果文件系统的有些文件名中包含空格,find命令的-print0选项可以使用0(NULL)来分隔查找到的元素,然后再用xargs对应的-0选项进行解析

# 在Samba挂载的文件系统中搜索.docx文件,这些文件名中通常会包含大写字母和空格。
# 其中使用了grep找出内容中不包含image的文件
$ find /smbMount -iname '*.docx' -print0 | xargs -0 grep -L image
# 1. 读取stdin,为命令传入格式化参数
#!/bin/bash
# cecho.shecho $*'#'## 当参数被传递给文件cecho.sh后,它会打印这些参数并以#字符结尾$ ./cecho.sh arg1 arg2
arg1 arg2 ## 1. 有一个包含着参数列表的文件(每行一个参数)要提供给某个命令(比如cecho.sh)
# 需要以不同的形式来应用这些参数。在一种形式中,每次调用提供一个参数
$ ./cecho.sh arg1
$ ./cecho.sh arg2
$ ./cecho.sh arg3# 2. 每次调用提供一到两个参数
$ ./cecho.sh arg1 arg2
$ ./cecho.sh arg3# 3. 在单词调用中提供所有参数
$ ./cecho.sh arg1 arg2 arg3# args.txt
$ cat args.txt
arg1
arg2
arg3$ cat args.txt | xargs -n 1 ./cecho.sh
arg1 #
arg2 #
arg3 #$ cat args.txt | xargs -n 2 ./cecho.sh
arg1 arg2 #
arg3 #$ cat args.txt | xargs ./cecho.sh
arg1 arg2 arg3 ## 在上面的例子中,由xrags添加的参数都被放置在指定命令的尾部,但有时可能需要在命令末尾有一个固定的参数,并希望xargs能够替换居中的参数
## ./cecho.sh -p arg1 -l
## 在命令执行过程中,arg1是唯一的可变内容,其余部分都保持不变
## xargs有一个-I,可以用于指定替换字符串,这个字符串会在xargs解析输入时被参数替换掉
$ cat args.txt | xargs -I {} ./cecho.sh -p {} -l
-p arg1 -l #
-p arg2 -l #
-p arg3 -l #

-I {}指定了替换字符串,为该命令提供的各个参数会通过stdin读取并依次替换字符串{}

使用-I的时候,命令以循环的方式运,如果有3个参数,那么命令就会连同{}一同被执行3次。{}会在每次执行中被替换为相应的参数

  1. 结合find使用xargs
# 下面这样做很危险,有可能会误删文件,无法预测find命令输出的分隔符究竟是什么'\n'还是' '。
# 如果文件名中包含空格符,xargs会将其误认为是分隔符
# 如 bashrc text.txt会被视为bashrc和text.txt
$ find . -type f -name "*.txt" -print | xargs rm -f

使用find命令的-print0选项可以生成以空字符(’\0’)作为分隔符的输出,然后将其作为xargs命令的输入

$ find . -type f -name "*.txt" -print0 | xargs -0 rm -f
  1. 统计源代码目录中所有C程序文件的行数
    行数(Lines of Code, LOC)
$ find source_code_dir_path -type f -name "*.c" -print0 | xargs -o wc -l
  1. 结合stdin,巧妙运用while语句和子shell
    xargs会将参数放置在指定命令的尾部,因此无法为多组命令提供参数,可以通过创建子shell来处理这种复杂情况。子shell利用while循环读取参数并执行命令
$ cat file.txt | (while read arg; do cat $arg; done)
# 等同于cat files.txt | xargs -I {} cat {}

在while循环中,可以将cat $arg替换成任意数量的命令,这样就可以对同一个参数执行多个命令。也可以不借助管道将输出传递给其它命令。这种利用()创建子shell的技巧可以应用于多种问题场景。子shell操作符内部的多条命令在执行时就像一个整体

$ cmd0 | (cmd1;cmd2;cmd3) | cmd4

shell的-c选项可以调用子shell来执行命令行脚本,可以于xargs结合解决多次替换的问题,下列命令找出了所有C文件并显示出每个文件的名字,文件名前会加上一个换行符(-e选项运行进行转义替换)

$ find . -name '*.c' | xargs -I ^ sh -c "echo -ne '\n ^: '; grep main ^"

用tr进行替换

tr可以对来自标准输入的内容进行字符替换、字符删除以及重复字符压缩
tr是translate的简写,因为它可以将一组字符转换成另一组字符

tr只能通过标准输入接收输入,无法通过命令行参数接收

$ tr [options] set1 set2

来自标准输入的输入字符会按照位置从set1映射到set2(set1中的第一个字符映射到set2中的第一个字符,以此类推),然后将输出写入到stdout
set1和set2是字符类或字符组,如果两个字符组的长度不相等,那么set2会不断复制其最后一个字符,直到长度与set1相同;如果set2的长度大于set1,那么在set2中超出set1长度那部分字符则被全部忽略

$ echo "HELLO WHO IS THIS" | tr 'A-Z' 'a-z'
hello who is this

将字符从一个集合映射到另一个集合

$ echo 12345 | tr '0-9' '9876543210'
87654 # 已加密$ echo 87654 | tr '9876543210' '0-9'
12345 # 已解密

tr命令可用于加密,ROT13是一个著名的加密算法,此算法中,字符会被移动13个位置,因此文本加密和解密都使用同一个函数

tr还可以把制表符转换成单个空格

$ tr '\t' ' ' < file.txt
  1. 用tr删除字符,-d,指定要删除的字符集合
$ echo "Hello 123 world 456" | tr -d '0-9'
Hello world
# 将stdin中的数字删除并打印删除后的结果
  1. 字符集补集
# tr -c [set1] [set2]
# 如果只给出set1,那么tr将删除所有不在set1中的字符
# 同时给出set1和set2的话,tr会将不再set1中的字符转换成set2中的字符
# 如果给出了-c选项,则需要同时给出set1和set2
# 如果同时给出了-c和-d选项,则只能给出set1,其它所有字符都会被删除$ echo hello 1 char 2 next 4 | tr -d -c '0-9 \n'
124$ echo hello 1 char 2 next 4 | tr -c '0-9' ' '1  2   4
  1. 用tr压缩字符
    tr可以删除字符串中重复出现的字符
# tr -s '[需要压缩的一组字符]'
$ cat multi_blanks.txt | tre - s '\n'
line 1
line 2
line 3
line 4# tr可以将文件中的数字列表进行相加
$ cat sum.txt
1
2
3
4
5$ cat sum.txt | echo $[$(tr '\n' '+') 0 ]
15$ cat text.txt
first 1
second 2
third 3$ cat test.txt | tr -d [a-z] | echo "total: $[$(tr ' ' '+')]"
total: 6
  1. 字符类

alnum 字母和数字
alpha 字母
cntrl 控制(非打印)字符
digit 数字
graph 图形字符
lower 小写字母
print 可打印字符
punct 标点符号
space 空白字符
upper 大写字母
xdigit 十六进制字符

tr '[:lower:]' '[:upper:]'

校验与核实

通过比对下载文件和原始文件的校验和,能够合适接收到的文件是否正确
如果源位置上的校验和与目的地上接收文件的校验和相等,就意味着我们接收到的文件没有问题

Unix和Linux支持多种校验和程序,但是常用的是MD5和SHA-1

$ md5sum filename
52a1aedd6a17fdad7818d0bf799a890c
# md5sum是一个长度为32个字符的十六进制串
$ md5sum file1 file2 file3
[checksum1] file1
[checksum1] file2
[checksum1] file3$ md5sum -c file_sum.md5
# 检验校验和是否匹配$ md5sum -c *.md5
# 用所有的md5信息来检查所有文件# SHA-1给出一个长度为40个字符的十六进制串
$ sha1sum filename

对目录进行校验

校验和是从文件中计算得来的,对目录进行校验和意味着需要对目录中的所有文件以递归的方式进行计算
md5deep或sha1deep命令可以遍历目录树,计算其中所有文件的校验和

$ md5deep -rl directory_path > directory.md5
# -r 使用递归遍历
# -l 使用相对路径,默认路径,md5deep会输出文件的绝对路径
$ find directory_path -type f -print0 | xargs -0 md5sum >> directory.md5
$ md5sum -c directory.md5
$ md5sum file
52a1aedd6a17fdad7818d0bf799a890c  tmp
$ sha1sum file
20ce7b1832443054086668f4a9423bc344171a75  tmp

md5和sha1都是单向散列算法,均无法逆推出原始数据,两者通常用于为特定数据生成唯一的密钥
这类散列算法多用于存储密码,密码只存储其对应散列值。如果需要认证某个用户,则读取该用户提供的密码并转换为散列值,然后与之前存储的散列值进行比对,如果相同,用户则通过认证并授权访问

尽管应用广泛,md5sum和sha-1已不再安全,推荐使用bcrypt或sha512sum这类工具进行加密

shadow-like散列(加盐散列)

在linux中,用户密码是以散列值形式存储在文件/etc/shadow中
shadow密码通常是加盐密码(salted password),所谓的“盐”就是一个额外的字符串,起混淆的作用,使加密更加难以破解
盐是由一些随机位组成的,它们作为密钥生成函数的输入之一,产生密码的加盐散列

将salt_string替换为随机字符串并将PASSWORD替换成想要使用的密码

加密工具与散列

加密技术主要用于防止数据遭受未经授权的访问。和上面讲的校验和算法不同,加密算法可以无损地重构原始数据,可用的加密算法有很多,下面将讨论Linux/Unix中最常用的那些

crypt

crypt命令通常并没有安装在Linux系统中。它是一个简单的加密工具,相对而言不是那么安全,该命令从stdin接受输入,要求用户创建口令,然后将加密数据输出到stdout

$ crypt <input_file >output-file
Enter passphrase:
$ crypt PASSPHRASE <input_file >encrypted_file
$ crypt PASSPHARSE -d <encrypted_file >output_file
# 解密文件

gpg(GNU privacy guard)

是一种应用广泛的工具,它使用加密技术来保护文件,以确保数据在送达目的地之前无法被读取

gpg签名同样广泛用于E-mail通信中的邮件“签名”,以证明发送方的真实性

$ gpg -c filename
# 加密文件
$ gpg filename.gpg
# 解密文件

Linux Shell脚本攻略-玩转xargs相关推荐

  1. LINUX SHELL脚本攻略笔记[速查]

    LINUX SHELL脚本攻略笔记[速查] Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgr ...

  2. Linux Shell脚本攻略 读书笔记

    内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...

  3. linux shell 脚本 supress,《linux Shell 脚本攻略》进阶学习(第一部分)

    第二章命令之乐 cat 不仅可以读取文件并且连接数据,它还能从标准输入中进行读取 要从标准输入中读取,就要使用管道操作符 echo 'Text through stdin' | cat - file. ...

  4. 《Linux Shell脚本攻略》学习笔记-第一章

    1.1 简介 计算机可以从文本文件(称为shell脚本)中读取并执行命令. sehll脚本不仅节省了时间,而且清楚明白地表明了所执行的操作. bash shell变成了UNIX和Linux中既成事实的 ...

  5. linux shell脚本攻略 第二章 命令之乐 cat,find,tr,sort,uniq,split等

    目录 1. 使用cat进行拼接 2.录制并回放终端会话 3.find命令 4. xargs命令 5. tr命令进行转换 6.校验和与核实(md5) 7.加密工具与散列 8.排序,唯一与重复 9.临时文 ...

  6. linux shell脚本攻略_(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤...

    今天为大家带来的内容是:(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤 本文内容主要介绍了Linux下shell脚本监控Tomcat的状态并实现自动启动的步骤,文章 ...

  7. Linux Shell脚本攻略学习总结:一

    终端打印 终端打印的常用命令有两个:echo和print 首先,我先介绍echo 1.echo echo这个命令接受三种形式的参数,实例如下: echo "Hello World" ...

  8. linux shell脚本攻略第3版_「技术干货」师傅说不会写shell脚本的网安不是一个好黑客,实战...

    shell脚本? 在说什么是shell脚本之前,先说说什么是shell. shell是外壳的意思,就是操作系统的外壳.我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就 ...

  9. Linux Shell脚本攻略-调试脚本+函数和参数

    调试脚本 可以利用Bash内建的调试工具或按照易于调试的方式编写脚本 # 1. 使用选项-x,启用shell脚本的跟踪调试功能 $ bash -x script.sh # 打印出所执行的每一行命令以及 ...

最新文章

  1. mysql中leave和_MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法
  2. 用java编写一个函数,统计一个字符串中每个字母出现的次数
  3. BERT却不懂Transformer?2021
  4. C++二个数组求并集的实现算法(附完整源码)
  5. 履约时间预估:如何让外卖更快送达?
  6. cve20190708补丁的kb名称_微软KB4495667补丁(CVE 2019-0708补丁)V1.1 官方版
  7. C语言中连续两个printf,在C中两个连续的printf()调用的奇怪行为
  8. 一名合格前端工程师的进阶指南!都来认真看一下吧
  9. 报错:Uncaught TypeError: 获取的元素节点.setAttribute is not a function
  10. 如何精通C++ 摘自知乎和quora
  11. iOS学习-UITextField设置placeholder的颜色
  12. paip.c#.net自定义图像窗体form
  13. MySQLl数据量不一样,导致走不同的索引
  14. python-随机生成数据faker
  15. u盘插电脑显示跟这台计算机,五大步骤解决U盘插入电脑盘符不显示问题
  16. 角色与使命:学生干部如何平衡工作与学习的关系?
  17. 2019安徽省程序设计竞赛 D自驾游 题解
  18. PAT-ADVANCED1118——Birds in Forest
  19. 购物全返模式是什么?解析购物的盈利模式
  20. 我的2007-高开低走,无甚成就

热门文章

  1. 一个关于android旋转屏幕界面的方法
  2. Pytorch输出网络中间层特征可视化
  3. 论文学习——一种基于DTW的符号化时间序列聚类算法
  4. 基于JAVA高校后勤保修系统计算机毕业设计源码+数据库+lw文档+系统+部署
  5. 求三角锥体积用c语言,求三角锥体积公式的推导?
  6. windows虚拟桌面_如何在Windows 10的新虚拟桌面中打开应用程序或文件
  7. 多个邮箱逗号隔开正则表达式
  8. Fantasy Mix-Lingual Tacotron Version 4: Google-ZYX-Phoneme-HCSI-DBMIX
  9. python应用之复习计划生成器
  10. 【adb】 win11 配置 adb环境 史上最详细