Unix/bash中如何正确编写循环处理序列数字命名的文件
问题描述
目录下存在一批命名格式为file_0.5_1.5_xxxx.txt、file_1.5_2.5_xxxx.txt……file_1000.5_1001.5_xxxx.txt的文件,需要编写Unix/bash循环对每个文件执行grep 'house'操作,并将结果输出到原文件名后添加2的对应文件(例如file_0.5_1.5_xxxx2.txt)。
尝试编写了如下循环,但无法通过${i+1}正确计算数值:
for i in {0..1000}; do grep house file_${i}.5_${i+1}.5_xxxx.txt > file_${i}.5_${i+1}.5_xxxx2.txt; done
解决方案
问题原因
bash中${i+1}属于参数扩展语法,作用是检查变量i是否已定义:若i存在,则替换为1;若i不存在,则替换为空。它并不是用来做数值加法的,因此无法得到i+1的计算结果。
修正方案1:使用算术扩展计算数值
改用bash的算术扩展$((i+1))来计算i加1的结果,修正后的代码如下:
for i in {0..1000}; do grep 'house' "file_${i}.5_$((i+1)).5_xxxx.txt" > "file_${i}.5_$((i+1)).5_xxxx2.txt" done
如果需要提高可读性,可以先把计算结果存到变量中:
for i in {0..1000}; do upper_bound=$((i + 1)) grep 'house' "file_${i}.5_${upper_bound}.5_xxxx.txt" > "file_${i}.5_${upper_bound}.5_xxxx2.txt" done
修正方案2:直接遍历目标文件(更灵活)
如果担心循环中存在对应编号的文件缺失的情况,可以直接匹配所有符合命名格式的文件,通过字符串替换生成输出文件名,无需计算数值:
for file in file_*.5_*.5_xxxx.txt; do grep 'house' "$file" > "${file%.txt}2.txt" done
这里${file%.txt}是去掉文件名末尾的.txt,再拼接2.txt即可得到目标输出文件名。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

