2017-01-12 48 views
-2

我试图通过各种线程在线排序,并且无法确定如何将输出管道输送到后续命令。我正在使用批处理脚本(通过bash)通过独立程序连接多个文件,这需要输入为特定格式。

在程序中级联的标准命令是:

fslmerge -t $OUTPUT $INPUT1 $INPUT2... $INPUT n 

我已经尝试了几种方法来定义输入文件,与下面的最近一次尝试。

file=$INPUTDIR/sublist.txt 
    while read -r SUBJ; do 

for cond in "med" "nomed"; do 

for n in {01..10}; do 

INPUT="stage2_${SUBJ}_${cond}_00${n}.nii.gz" 

fslmerge -t $OUTPUT/stage2_ic00${n}_${cond}.nii.gz `ls $INPUTDIR/$INPUT` 

done; done; done < $file 

然而,这导致在运行上的每个输入的命令分别对所有输入上运行命令(如上面在“标准命令”指出):

fslmerge -t $OUTPUT $INPUTDIR/subject1 
fslmerge -t $OUTPUT $INPUTDIR/subject2 
... 
fslmerge -t $OUTPUT $INPUTDIR/subject10 

编辑: 的sublist.txt列出如下。它们按顺序堆叠,我需要它们通过fslmerge连接起来。

SUB003 
SUB006 
SUB007 
SUB010 
SUB011 
SUB001 
SUB004 
SUB008 
SUB009 

对于每个条件(med,no med),每个主题都有多个组件(n)。最终,我需要运行该命令,以便连接给定条件和组件的所有主题。一个例子是:

fslmerge -t $OUTDIR/stage2_ic0001_med.nii.gz stage2_SUB003_med_0001.nii.gz stage2_SUB006_med_0001.nii.gz stage2_SUB007_med_0001.nii.gz ... stage2_SUB009_med_0001.nii.gz 

我会非常感谢任何输入的问题和/或简化方法!我在编码方面比较新,对任何术语错误都表示真诚的歉意。我意识到我的尝试可能严重脱离这个世界。

+0

你能澄清你想要它做什么吗?特别是,它应该在sublist.txt中为每一行运行'fslmerge',或者每行运行两次(一次使用cond =“med”,一次使用cond =“nomed”),或者二十次(每次组合一次cond和n)?如果是最后一个,那么输入文件是什么(你似乎只显示每个SUBJ/cond/n组合的一个输入);如果它不是最后一个,输出文件应该是什么(你似乎显示cond,而n是文件名的一部分)。 –

+0

一般的想法是将所有输入文件名添加到数组中,然后使用'“$ {array [@]}”'把它们全部放在命令的末尾。但我也不明白你想怎么做,因为你的输出文件对于每个输入文件都是不同的。 – Barmar

+0

嗨戈登,非常感谢您的帮助!你的问题非常好,我认为这是我搞乱的地方,并且一直对如何进行感到困惑。这是你给出的最后一个例子:每个主题(SUBJ)有两个条件(med,no med)。对于每个条件,每个主题都有多个组件文件(n)。 – edub

回答

2

如果我的理解正确,您希望为每个cond/n组合运行命令,并合并所有主题(即sublist.txt中列出的所有人)的输入文件。是对的吗?如果是的话,我会做的是所有科目存储在数组中,然后使用该数组生成输入文件的列表中为每个主题:

subjectsfile=$INPUTDIR/sublist.txt 
subjects=() 
inputfileprefixes=() 
while read -r subj; do 
    subjects+=("$subj") # this isn't really needed, since we don't use the list directly. 
    inputfileprefixes+=("$INPUTDIR/stage2_$subj") 
done <"$subjectsfile" 

for cond in "med" "nomed"; do 
    for n in {1..20}; do 
     fslmerge -t "$OUTPUT/stage2_ic00${n}_${cond}.nii.gz" "${inputfileprefixes[@]/%/_${cond}_00${n}.nii.gz}" 
    done 
done 

这里有一些略重阵挂羊头卖狗肉。像"${arrayname[@]/%/something}"这样的东西需要一个数组,并在每个元素的末尾粘贴“某物”。所以说主题是“爱丽丝”,“鲍勃”和“塞西尔”,INPUTDIR是“/某些/路径”。然后subjects被设置为("alice" "bob" "cecil"),inputfileprefixes被设置为("/some/path/stage2_alice" "/some/path/stage2_bob" "/some/path/stage2_cecil"),并且对于每个cond/n组合,它在适当的后缀上粘贴并将该列表传递给fslmerge,所以命令如fslmerge -t $OUTPUT/stage2_ic001_med.nii.gz /some/path/stage2_alice_med_001.nii.gz /some/path/stage2_bob_med_001.nii.gz /some/path/stage2_cecil_med_001.nii.gz那样出现。

警告:这没有完全测试,我不完全确定我理解这个问题的权利。在执行此操作前备份一切重要的东西,以防它做一些愚蠢的事情。顺便说一下,我建议不要使用全大写的变量名(有些是保留的,你会错误地使用其中的一个,奇怪的事情会发生)。另外,在变量的值包含空格或其他shell元字符的情况下,对包含变量扩展的字符串进行双引号是个好主意(就像我在"$OUTPUT/stage2_ic00${n}_${cond}.nii.gz"中所做的那样)。

+1

难道你不能直接在第一个循环中执行'inputfileprefixes + =(“$ INPUTDIR/stage2_ $ subj”)'吗? – melpomene

+0

@melpomene:好主意;编辑来... –

+0

@戈登:非常感谢!这很好,我真的很感谢你抽出时间来解释一切,特别是我似乎很难解释这个问题。干杯! :) – edub