【发布时间】:2017-01-12 16:18:08
【问题描述】:
我有一个文件列表:
file_name_FOO31101.txt
file_name_FOO31102.txt
file_name_FOO31103.txt
file_name_FOO31104.txt
我想使用成对的文件输入到下游程序中,例如:
program_call file_name_01.txt file_name_02.txt
program_call file_name_03.txt file_name_04.txt
...
我不想要:
program_call file_name_02.txt file_name_03.txt
我需要循环执行如下:
#!/bin/bash
FILES=path/to/files
for file in $FILES/*.txt;
do
stem=$( basename "${file}" ) # stem : file_name_FOO31104_info.txt
output_base=$( echo $stem | cut -d'_' -f 1,2,3 ) # output_base : FOO31104_info.txt
id=$( echo $stem | cut -d'_' -f 3 ) # get the first field : FOO31104
number=$( echo -n $id | tail -c 2 ) # get the last two digits : 04
echo $id $((id+1))
done
但这不会产生我想要的。
在每个循环中,我想调用一个程序一次,输入两个文件(第一个文件的最后 2 位总是奇数 01,第二个文件的后 2 位总是偶数 02)
【问题讨论】:
-
顺便说一句,全大写的变量名是specified by POSIX,供对系统或shell有意义的变量使用,而小写的变量名则保留给应用程序使用。考虑在您自己的代码中遵循这一点,以防止任何可能错误地踩踏对系统有意义的变量。 (这个规范对环境变量是明确的,但是设置一个常规的 shell 变量会覆盖任何类似命名的环境变量,所以它们共享一个命名空间)。
-
顺便说一句,如果您的
FILES路径包含任何空格,$FILES/*.txt将中断,因此"$FILES"/*.txt。 -
@CharlesDuffy - 谢谢 - 很高兴知道这一点
-
顺便说一句,与本机字符串操作原语相比,使用
cut和tail等外部命令的所有操作都非常慢。我在答案中添加了附录;另请参阅 BashFAQ #100 和 the bash-hackers page on parameter expansion。 -
...对我的回答所涉及的内容提供更完整的解释,回复:
$((id + 1))——假设你的意思是$(( number + 1 ))(因为$id是一个以开头的字符串非数字字符):如果数字的第一个字符是0,则将其解释为八进制;因此,echo $(( 010 ))发出 8,echo $(( 09 ))导致“值对于基础而言太大”错误;因此在我的回答中需要$((10#$number))以强制解释为十进制。
标签: bash for-loop file-processing