여러 쌍의 파일 이름을 바꾸고 그 사이에 있는 다른 바코드 문자열을 제거하시겠습니까?

여러 쌍의 파일 이름을 바꾸고 그 사이에 있는 다른 바코드 문자열을 제거하시겠습니까?

파일 중간에 원치 않는 바코드 레이블이 있는 페어링된 파일이 많이 있습니다. 예를 들면 다음과 같습니다.

LIB008983_TRA00020080_TAAGGCGA-TATCCTCT_L001_R1.fastq.gz
LIB008983_TRA00020080_TAAGGCGA-TATCCTCT_L001_R2.fastq.gz
LIB008983_TRA00020081_TAAGGCGA-AGAGTAGA_L001_R1.fastq.gz
LIB008983_TRA00020081_TAAGGCGA-AGAGTAGA_L001_R2.fastq.gz
LIB008983_TRA00020082_TAAGGCGA-GTAAGGAG_L001_R1.fastq.gz
LIB008983_TRA00020082_TAAGGCGA-GTAAGGAG_L001_R2.fastq.gz
LIB008983_TRA00020083_TAAGGCGA-ACTGCATA_L001_R1.fastq.gz
LIB008983_TRA00020083_TAAGGCGA-ACTGCATA_L001_R2.fastq.gz

파일의 시작이나 끝 부분에 있는 식별자를 수정하지 않고 바코드(파일 전체에 걸쳐 다름)를 제거해야 합니다.

나는 온라인에서 읽은 내용을 바탕으로 직접 스크립트를 작성해 보았지만 상대적으로 좋지 않은 시도처럼 보였습니다.

for f in LIB008983_TRA000{19916..20167}_*_L001_R*.fastq.gz;
do
  newName=${f/_*_\ _L001_R*.fastq.gz}
  mv -i "$f" "$newName";
done

내가 받은 오류 메시지는 다음과 같습니다.

mv: cannot stat ‘LIB008983_TRA00019917_*_L001_R*.fastq.gz’: No such file or directory

이상적으로 최종 파일 이름은 다음과 같습니다.

LIB008983_TRA00020136_L001_R1.fastq.gz
LIB008983_TRA00020136_L001_R2.fastq.gz
LIB008983_TRA00020137_L001_R1.fastq.gz
LIB008983_TRA00020137_L001_R2.fastq.gz
..
..

등.

답변1

여기서 보고 있는 문제는 for루프가 예상하지 못한 방식으로 확장된다는 것입니다. 범위 {...}연산자는 존재하는 파일 이름뿐만 아니라 가능한 모든 파일 이름의 전체 목록을 제공합니다.

예를 들어 파일 19917이 존재하지 않아 이 mv오류 메시지가 발생합니다.

echo다음을 배치하여 이를 확인할 수 있습니다 .

for f in LIB008983_TRA000{19916..20167}_*_L001_R*.fastq.gz
do
  echo "$f"
done

그러면 다음과 같은 출력이 제공됩니다.

LIB008983_TRA00019916_*_L001_R*.fastq.gz
LIB008983_TRA00019917_*_L001_R*.fastq.gz
LIB008983_TRA00019918_*_L001_R*.fastq.gz
...
LIB008983_TRA00020078_*_L001_R*.fastq.gz
LIB008983_TRA00020079_*_L001_R*.fastq.gz
LIB008983_TRA00020080_TAAGGCGA-TATCCTCT_L001_R1.fastq.gz
LIB008983_TRA00020080_TAAGGCGA-TATCCTCT_L001_R2.fastq.gz
...
LIB008983_TRA00020084_*_L001_R*.fastq.gz
LIB008983_TRA00020085_*_L001_R*.fastq.gz
LIB008983_TRA00020086_*_L001_R*.fastq.gz

.가 있는 모든 줄은 *존재하지 않는 파일을 나타냅니다.

이 문제를 해결하는 방법에는 두 가지가 있습니다. 먼저 범위를 유지하려면 다음을 테스트하십시오 mv.

  if [ -f "$f" ]
  then
    mv -i "$f" "$newName"
  fi

이제 mv파일이 존재하는 경우에만 명령이 실행됩니다.

두 번째 방법은 범위에 관심이 없다면 glob 패턴을 일치시키는 것입니다.

for f in LIB008983_TRA000*_*_L001_R*.fastq.gz
do
  newName=${f/_*_\ _L001_R*.fastq.gz}
  mv -i "$f" "$newName"
done

mv두 경우 모두 더 이상 존재하지 않는 파일을 시도하지 않습니다 .

참고로 이들 중 일부는 필요하지 않으므로 ;답변에서 제거했습니다.

두 번째 문제가 있습니다. "$newName"이 원하는 것이 아닙니다. 저는 구식 ksh코더이고 이를 표현하는 더 좋은 방법이 있을 수 있지만 bash다음과 같은 작업을 수행하겠습니다.

  tail=L${f##*_L}
  head=${f%_*_$tail}_
  newName="$head$tail"
  mv -i "$f" "$newName"

이제 입력 파일 목록이 주어지면

LIB008983_TRA00020080_L001_R1.fastq.gz
LIB008983_TRA00020080_L001_R2.fastq.gz
LIB008983_TRA00020081_L001_R1.fastq.gz
LIB008983_TRA00020081_L001_R2.fastq.gz
LIB008983_TRA00020082_L001_R1.fastq.gz
LIB008983_TRA00020082_L001_R2.fastq.gz
LIB008983_TRA00020083_L001_R1.fastq.gz
LIB008983_TRA00020083_L001_R2.fastq.gz

관련 정보