Linux - shell - xargs - 基础
-
概述
- 简述 xargs 的使用
-
背景
- 尝试批量操作文件
- 发现一些问题小问题
- 然后, 尝试解决
- 尝试批量操作文件
-
准备
- 环境
- OS
- centos7
- OS
- 环境
1. 操作: 尝试创建多个 文本文件
- 概述
- 尝试创建多个文本文件
1. 思路1: 一个一个手动创建
-
这个...
- 这个我不说, 你们都知道...
- 有点费时间
-
示例
# 真, 一个一个 > touch file1 > touch file2 # 稍微机灵点的一个一个 > touch file1 file2
2. 思路2: 循环创建
-
前提
- 熟悉 shell 的循环语法
- 文件名有一定的规律
-
示例
# 简单规律 > touch file{1..2} # 稍微麻烦点的 > for i in {1..2};do touch file$[i*2];done
3. 思路3: 文件列表
-
前提
-
文件名可能没有那么有规律
-
但是有 明确的文件列表
-
filelist
file1 file2
-
-
示例1
> cat filelist | touch # 纳尼? 报错了...
-
结果: 无法运行
-
问题
- touch 为什么无法运行
-
解释
- touch 命令, 无法接受 管道输入
- | 是管道操作符
- touch 命令, 只能接受 参数
- touch 命令, 无法接受 管道输入
-
一说到参数
- 之前好像学过一点 xargs, 试试好使不好使
-
-
示例2
> cat filelist |xargs touch
-
结果
- 没啥问题
2. xargs
-
概述
- 一个常用命令
-
作用
- 将 管道 的输入, 转为 后续命令行 的参数
- 难怪经常和 | 一起出现
- 将 管道 的输入, 转为 后续命令行 的参数
-
使用
- 后续命令不接受管道时, 可以尝试用 xargs 试试
3. 场景2: 根据文件列表, 复制文件
-
概述
- 尝试给 多参数命令, 传递参数
-
场景
- 创建多个文件的时候, 发现 其实每个文件, 都有基本的 模板
- 我先建立一个模板
- temp
- 假如, 我可以按照文件列表, 把 模板 复制开来, 就能省很多事
1. 思路1: 直接复制
- 略
- 这个大家都会
2. 思路2: 循环复制
- 略
- for 循环得获取文件列表
- 这块我还不太熟悉, 没法讲...
- for 循环得获取文件列表
3. 思路3: xargs
-
尝试1: 先试试一个文件
-
copylist
temp file1
-
命令
> cat copylist | xargs cp
-
结果
- 没有问题
-
-
尝试2: 一个文件好了, 我试试多个
-
copylist
temp file1 temp file2
-
命令
> cat copylist | xargs cp
-
结果
-
报错
# 什么鬼? cp: target ‘file2’ is not a directory
-
-
-
疑问
- 执行了这么多年的 cp, 没见过这种错误啊
- 不过 cp 多参数的时候, 好像会出这种错
- 可这命令到底是 怎么执行的呢?
- 执行了这么多年的 cp, 没见过这种错误啊
-
xargs -p
-
概述
- 一个 确认机制
-
确认机制
- 打印即将执行的命令
- 是否执行
- 确认输入 y
- 取消输入 n
-
命令
> cat copylist | xargs -p cp
-
结果
# 原来执行的, 是这种命令... # 这种形式的 cp, 将 前面 n-1 项 视为需要拷贝的内容, 拷贝到某个目录下面 # 所以, 最后一项, 必须要是一个 目录 cp temp file1 temp file2 ?...
-
原因
- xargs 从 stream 里获取的内容, 最后都 成了 一行
-
好了, 这下要解决另一个问题
- 如果能把这些内容, 每次取两个取出来, 是不是就行了
- 是的
- 如果能把这些内容, 每次取两个取出来, 是不是就行了
-
-
xargs -n
-
概述
- 截断输出, 每次传递 n 个作为 命令参数
-
命令
# 如果想进一步确认, 可以在 2 后面加上 -p > cat copylist | xargs -n 2 cp
-
结果
- 这下好了
-
-
其实还可以这样
-
命令
# 这样的话, 文件列表里, 就可以只有 目标文件名 了 > cat filelist | xargs -n 1 cp temp
-
疑问
- 如果我的参数, 在 命令中间, 怎么办...
- 这个也可以解决...
- 如果我的参数, 在 命令中间, 怎么办...
-
-
xargs -i
-
命令
# 将 文件列表 里的内容, append 到 log 里 # 文件名里如果有空格, 一定要用这玩意来处理 # {} 代表每次 每次取出的内容 > cat filelist | xargs -n 1 -i cat {} >> log
-
ps
-
ref
-
- 阮老师的教程, 聊胜于无吧
-
-
后续
- 如果遇到 更复杂的情况
- 比如, 这次 2 个参数, 下次 3 个参数, 再下次 1 个参数的..
- 就不知道怎么搞了...
- 老老实实写脚本吧? 还是有别的办法?
- 如果遇到 更复杂的情况
尽量尝试解释清楚; 自己校对能力有限, 如果有错误欢迎指出