我有一个文件列表,其中两个后续的文件总是在一起。我想在每次迭代时从for list中提取一个for循环提取两个文件,然后一次处理这两个文件(举个例子,让我们说我想要连接,即cat这两个文件)。
在一个简单的例子中,我的文件列表如下:
FILES="file1_mateA.txt file1_mateB.txt file2_mateA.txt file2_mateB.txt"
我可以破解它并说出
FILES="file1 file2"
for file in $FILES
do
actual_mateA=${file}_mateA.txt
actual_mateB=${file}_mateB.txt
cat $actual_mateA $actual_mateB
done
但我希望能够处理配对A和配偶B具有任意名称的列表,例如:
FILES="first_file_first_mate.txt first_file_second_mate.txt file2_mate1.txt file2_mate2.txt"
有没有办法从每次迭代的$ FILES中提取两个值?
答案 0 :(得分:21)
使用数组作为列表:
files=(fileA1 fileA2 fileB1 fileB2)
for (( i=0; i<${#files[@]} ; i+=2 )) ; do
echo "${files[i]}" "${files[i+1]}"
done
答案 1 :(得分:8)
您可以使用xargs(1),例如
ls -1 *.txt | xargs -n2 COMMAND
开关-n2让xargs从管道输出中选择2个连续的文件名来传递命令
成对连接10个文件file01.txt ... file10.txt 可以使用
ls *.txt | xargs -n2 sh -c 'cat $@ > $1.$2.joined' dummy
获取5个结果文件
file01.txt.file02.txt.joined
file03.txt.file04.txt.joined
file05.txt.file06.txt.joined
file07.txt.file08.txt.joined
file09.txt.file10.txt.joined
请参阅'info xargs'以获取解释。
答案 2 :(得分:2)
您可以从while循环中读取值,并使用xargs将每个读取操作限制为两个标记。
files="filaA1 fileA2 fileB1 fileB2"
while read a b; do
echo $a $b
done < <(echo $files | xargs -n2)
答案 3 :(得分:1)
这个怎么样:
park=''
for file in $files # wherever you get them from, maybe $(ls) or whatever
do
if [ "$park" = '' ]
then
park=$file
else
process "$park" "$file"
park=''
fi
done
在每次奇数迭代中,它只存储值(在park
中),然后在每次偶数迭代中使用存储的和当前值。
答案 4 :(得分:1)
您可以将字符串转换为数组,并按元素读取此新数组:
#!/bin/bash
string="first_file_first_mate.txt first_file_second_mate.txt file2_mate1.txt file2_mate2.txt"
array=(${string})
size=${#array[*]}
idx=0
while [ "$idx" -lt "$size" ]
do
echo ${array[$idx]}
echo ${array[$(($idx+1))]}
let "idx=$idx+2"
done
如果您的字符串中的分隔符与空格不同(即;
),则可以使用以下转换为数组:
array=(${string//;/ })
答案 5 :(得分:0)
您可以尝试这样的事情:
echo file1 file2 file3 file4 | while read -d ' ' a; do read -d ' ' b; echo $a $b; done
file1 file2
file3 file4
或者这个,有点麻烦的技术:
echo file1 file2 file3 file4 |tr " " "\n" | while :;do read a || break; read b || break; echo $a $b; done
file1 file2
file3 file4
答案 6 :(得分:0)
似乎awk
适合
$ awk '{for (i = 1; i <= NF; i+=2) if( i+1 <= NF ) print $i " " $(i+1) }' <<< "$FILES"
file1_mateA.txt file1_mateB.txt
file2_mateA.txt file2_mateB.txt
然后你可以通过设置IFS = $'\ n'
来循环它e.g。
#!/bin/bash
FILES="file1_mateA.txt file1_mateB.txt file2_mateA.txt file2_mateB.txt file3_mat
input=$(awk '{for (i = 1; i <= NF; i+=2) if( i+1 <= NF ) print $i " " $(i+1) }'
IFS=$'\n'
for set in $input; do
cat "$set" # or something
done
将尝试做什么
$ cat file1_mateA.txt file1_mateB.txt
$ cat file2_mateA.txt file2_mateB.txt
在没有匹配的情况下忽略奇怪的情况。