如何编写Bash脚本匹配两文件对应行并执行批量操作?
正确实现方案
原脚本错误说明
- 变量赋值语法错误:捕获命令输出需要用
$()包裹命令,且赋值语句等号两侧不能有空格,你写的user=cat users只会把user变量赋值为字符串cat,newuser= cat newusers的等号后有空格,会被识别为临时设置环境变量然后执行newusers命令,完全不符合预期。 - 循环逻辑错误:嵌套for循环会把
users中的每一行和newusers所有行逐一配对,不是按行一一对应;且遍历变量时需要加$符,for u in user只会遍历字符串user,不会读变量内容。 - 语法错误:bash的嵌套for循环写法不符合规范,缺少必要的分隔符和
do关键字。
方案1:逐行读取双文件(兼容性最好)
这个方法逻辑清晰,支持文件名带空格的场景,也不需要依赖额外命令:
#!/bin/bash # 绑定两个文件到不同文件描述符 exec 3<users exec 4<newusers # 逐行配对读取两个文件内容 while IFS= read -r old_name <&3 && IFS= read -r new_name <&4; do # 先保留echo运行一次,确认配对结果正确后再删除echo执行实际改名 echo mv -- "$old_name" "$new_name" done # 关闭文件描述符 exec 3<&- exec 4<&-
参数说明:
IFS=避免读取行时自动截断首尾空格read -r避免文件名中的反斜杠被自动转义mv后的--是为了兼容以-开头的文件名,防止被mv识别为参数
方案2:paste命令拼接(写法更简洁)
如果你的文件名中不包含制表符,用这个方法代码更短:
#!/bin/bash paste users newusers | while IFS=$'\t' read -r old_name new_name; do echo mv -- "$old_name" "$new_name" done
paste命令会默认按行配对两个文件的内容,用制表符分隔同一行的两个内容,直接读取即可完成配对。
如果两个文件行数不一致,两个方案都会自动在较短的文件读完后停止,不会执行错误的改名操作。
内容的提问来源于stack exchange,提问作者Samir Ahmadli
相关产品推荐
相关产品推荐

