for 循环同时匹配文件名的前面和后面

for 循环同时匹配文件名的前面和后面

我正在尝试设置一个 for 循环来对文件对运行进程。文件的名称看起来像这样

36_002_CGATGT_L001_R1_005.fastq.gz
36_002_CGATGT_L001_R2_005.fastq.gz

36_002_CGATGT_L001_R1_002.fastq.gz
36_002_CGATGT_L001_R2_002.fastq.gz

62_013_AGTCAA_L001_R1_003.fastq.gz
62_013_AGTCAA_L001_R2_003.fastq.gz

我需要在以下命令中使用每一对

sickle pe -f 36_002_CGATGT_L001_R1_005.fastq.gz \
 -r 36_002_CGATGT_L001_R2_005.fastq.gz\
 -o trimmed_36_002_CGATGT_L001_R1_005.fastq.gz\
 -p trimmed_36_002_CGATGT_L001_R2_005.fastq.gz\
 -s 36_002_CGATGT_L001_singles_005.fastq.gz

首先我正在尝试:

for n in *R1*; do m='basename $n R2' ; echo $m; done

但显然这种方法不起作用,因为文件名的前面和后面都很重要。我是否需要重命名文件,以便 R1 和 R2 成为名称的最后一部分?这会很尴尬,但并非不可能

答案1

如果您的 shell 支持 ksh${var/search/replace}形式的参数扩展 ( ksh93, zsh, mksh, yash, bash):

for r1 in *R1*; do
  r2=${r1/R1/R2}
  singles=${r1/R1/singles}
  trimmed1=trimmed$r1
  trimmed2=trimmed$r2
  sickle pe -f "$r1" \
   -r "$r2" \
   -o "$trimmed1" \
   -p "$trimmed2" \
   -s "$singles"
done

POSIXly,你可以做

 r2=${r1%%R1*}R2${r1#*R1}

答案2

假设我明白你在寻找什么,你可以使用以下方法解决它awk

#!/bin/bash
for file in *_R1_*; do 
    file=`basename $file`
    newFile=`echo $file | awk -F '_R1_' '{print $1}'`_R2_`echo $file | awk -F '_R1_' '{print $2}'`
    sName=`echo $file | awk -F '_R1_' '{print $1}'`_singles_`echo $file | awk -F '_R1_' '{print $2}'`
    echo $newFile
    rName="$newFile"
    oName="trimmed_$file"
    pName="$file"
done

相关内容