我正在编写运行软件的脚本。我正在尝试在 while 循环中添加函数来修剪变量中的文本,以便它可以在命令的其他部分中作为变量应用。但添加该功能的正确方法应该是什么?
--msa
这是仅运行一个文件时的工作代码。
while read -r i; do
raxml-ng --msa ../C049.laln_1l --model $i --prefix C049-rT;
done < ../C049.model
简单介绍一下,我使用的软件是 raxml-ng,运行该软件的参数是由--msa
、--model
、 和--prefix
文件中的每一个设置的。对于每个--msa
文件,它们都有相应的--model
和--prefix
.我将它们命名为相同的名称以简化脚本编写。例如,需要与和C049.laln_1l
匹配。C049.model
C049-rT
如上面的示例所示,如果我有其他--msa
具有相同扩展名的文件,我可以循环该命令,如下所示:
while read -r i; do
while read -r j; do
raxml-ng --msa ../$i.laln_1l --model $j --prefix $i-rT;
done < ../$i.model
done < msalist
现在我有一个要运行的文件列表--msa
(在 中列出msalist
),其中一些具有不同的文件扩展名。
该msalist
文件包含:
C049.laln_1l
C092.laln_1l
C016.laln_1l
gc30_part.cseq
gc3f.glist.cseq...
我命名了model
并prefix
仅使用第一个 之前的文本.
。
例如。参数列表model
:
C049.model
C092.model
C016.model
gc30_part.model
gc3f.model...
参数的情况也是一样prefix
。
因此,当编写 bash 脚本来循环查找--msa
中的所有文件时msalist
,我尝试使用 do"$( sed 's/\..*//g' "$i" )".model
来C049.model
代替C049.laln_1l.model
.但这似乎不起作用。
trees=$2
threads=$3
while read -r i; do
while read -r j; do
raxml-ng --msa ../"$i" --model "$j" --prefix "$( sed 's/\..*//g' "$i" )"-rT;
done < ../"$( sed 's/\..*//g' "$i" )".model;
done < "$alnlist"
如何修剪文本msalist
以便 和--model
阅读--prefix
?
答案1
要在任何 POSIX shell 中获取第一个之前的部分.
,您可以执行${var%%.*}
.所以在这里:
while IFS= read -r i; do
prefix=${i%%.*}
while IFS= read -r j; do
raxml-ng --msa ../"$i" --model "$j" --prefix "$prefix-rT";
done < "../$prefix.model";
done < "$alnlist
另请注意读取一行的语法是IFS= read -r line
, not read -r line
。
在这里,你还可以这样做:
while IFS=. read -r prefix rest; do
while IFS= read -r j; do
raxml-ng --msa ../"$prefix.$rest" --model "$j" --prefix "$prefix-rT";
done < "../$prefix.model";
done < "$alnlist
如果您想使用sed
删除以第一个开头的所有内容.
,请首先注意sed 's/\..*//'
删除.
后跟任意数量的字符其输入的每一行,而不是整个输入,并且您需要将 的内容$i
作为输入传递,而不是作为参数传递。sed
将其参数视为要从中读取输入的文件名,因此:
printf '%s\n' "$i" | sed 's/\..*//'
例如。尽管要删除整个输入中从第一个开始的所有内容.
,但最好是:
printf '%s\n' "$i" | sed '
:1
$!{
# except on the line line, append the next line to the
# pattern space and loop
N
b1
}
s/\..*//'