while 루프의 변수에 함수 추가

while 루프의 변수에 함수 추가

소프트웨어를 실행하기 위한 스크립트를 작성 중입니다. 변수의 텍스트를 잘라내어 명령의 다른 부분에서 변수로 적용할 수 있도록 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--prefixC049.laln_1lC049.modelC049-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.

그래서 find --msa의 모든 파일을 반복하는 bash 스크립트를 작성할 때 대신 msalistdo를 사용해 보았지만 작동하지 않는 것 같습니다."$( sed 's/\..*//g' "$i" )".modelC049.modelC049.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 셸에서 첫 번째 부분을 얻으려면 다음을 .수행하십시오 .${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가 아니라 입니다 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/\..*//'

관련 정보