本文介绍了成对处理文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我有一个文件列表: 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 我需要 $ p $ #!/ bin / bash FILES =路径/ to / files 用于$ FILES / *。txt文件; $ b $ 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)#获取第一个字段:FOO31104 number = $(echo -n $ id | tail -c 2)#得到最后两位:04 $ b $ echo $ id $((id + 1)) 完成 但是这不会产生我想要的。 在每个循环中,我要调用一次程序,并输入两个文件(第一个文件的最后两个数字总是奇数 01 ,第二个文件的最后两个数字总是偶数 02 ) 解决方案实际上我根本不会使用作为循环。 while 循环 shift s files off是完全合理的方式。 #在这里,我们用文件列表#覆盖参数列表... ...如果你想要的话,你可以在函数中做到这一点保持全局参数列表完好 set - $ FILES/ *。txt ##没有这些引号路径与空格破解 #处理没有找到匹配我们的文件的情况glob [[-e $ 1 || -L $ 1]] || {echo$ FILES中找不到.txt>& 2;出口1; ($$#> 1)); 在这里,我们正在做自己的循环, do ##在循环中只有w / 2或更多剩余 echo正在处理文件$ 1和$ 2## ...在这里替换你自己的逻辑... shift 2 || break ##即使测试不处理这种情况,也可以打破完成 #...并为有奇数个文件的情况添加自己的处理。 (($#))&&回声遗留文件$ 1仍然存在 请注意 $# / code> s在这里引用(())在StackOverflow的语法突出显示,而不是因为他们需要。 :) 顺便说一句 - 考虑使用bash的本地字符串操作。 $ b stem = $ {file ## * /} IFS = _ read -r p1 p2 id p_rest $ number $ $ $($ {#id} - 2))} output_base =$ {p1} $ {p2} $ {id} echo$ id $ ((10#number + 1))#10#确保解释为十进制,不是八进制 I have a list of files: file_name_FOO31101.txtfile_name_FOO31102.txtfile_name_FOO31103.txtfile_name_FOO31104.txtAnd I want to use pairs of files for input into a downstream program such as: program_call file_name_01.txt file_name_02.txtprogram_call file_name_03.txt file_name_04.txt...I do not want:program_call file_name_02.txt file_name_03.txtI need to do this in a loop as follows:#!/bin/bashFILES=path/to/filesfor 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))doneBut this does not produce what I want.In each loop I want to call a program once, with two files as input (last 2 digits of first file always odd 01, last 2 digits of second file always even 02) 解决方案 I actually wouldn't use a for loop at all. A while loop that shifts files off is a perfectly reasonable way to do this.# here, we're overriding the argument list with the list of files# ...you can do this in a function if you want to keep the global argument list intactset -- "$FILES"/*.txt ## without these quotes paths with spaces break# handle the case where no files were found matching our glob[[ -e $1 || -L $1 ]] || { echo "No .txt found in $FILES" >&2; exit 1; }# here, we're doing our own loop over those argumentswhile (( "$#" > 1 )); do ## continue in the loop only w/ 2-or-more remaining echo "Processing files $1 and $2" ## ...substitute your own logic here... shift 2 || break ## break even if test doesn't handle this casedone# ...and add your own handling for the case where there's an odd number of files.(( "$#" )) && echo "Left over file $1 still exists"Note that the $#s are quoted inside (( )) here for StackOverflow's syntax highlighting, not because they otherwise need to be. :)By the way -- consider using bash's native string manipulation.stem=${file##*/}IFS=_ read -r p1 p2 id p_rest <<<"$stem"number=${id:$(( ${#id} - 2 ))}output_base="${p1}${p2}${id}"echo "$id $((10#number + 1))" # 10# ensures interpretation as decimal, not octal 这篇关于成对处理文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!