Concatenar files en múltiples subdirectorys coincidentes

Necesito concatenar files en function del nombre del subdirectory en el que se encuentran. Los subdirectorys a veces tienen duplicates y otras no. La estructura del file se ve así:

  1. RootDir
    • 633
      • 633_S1_L001_R1_001.fastq
      • 633_S1_L001_R2_001.fastq
    • 739
      • 739_S1_L001_R1_001.fastq
      • 739_S1_L001_R2_001.fastq
    • 739 (1)
      • 739_S1_L001_R1_001.fastq
      • 739_S1_L001_R2_001.fastq
    • 739 (2)
      • 739_S1_L001_R1_001.fastq
      • 739_S1_L001_R2_001.fastq
    • 834
      • 834_S3_L001_R1_001.fastq
      • 834_S3_L001_R2_001.fastq
    • 834 (1)
      • 834_S7_L001_R1_001.fastq
      • 834_S7_L001_R2_001.fastq

Es el prefijo de 3 numbers y el número de R lo que importa, y el concat debe hacerse en R # 's coincidentes, con el número S que es variable.

  1. No se necesitaría concatenación para los files en dir 633
  2. Los 3 files R1 en los 739 directorys necesitarían concatenarse en order (739 primero, 739 (1) …)
  3. La salida debería ir a un subdirectory del subdirectory (/ RootDir / 739/739 / *)
  4. Al final, cada dir de salida final tendría un file R1 concatenado y un file R2.

Agradecería enormemente cualquier ayuda en la dirección correcta. También tenga en count que los files .fastq son simplemente files ASCII txt.

editar: Vi esta publicación un tanto relacionada , pero no he tenido éxito en usar el código allí debido al problema de varias carpetas coincidentes.

edit2: Ninguna de estas soluciones me funciona. Poco a poco voy combinando ideas que ambos me han dado y publicaré mi solución final aquí.

de acuerdo con su ejemplo, cualquier directory que tenga "duplicates" tiene un final duplicado en "(1)", entonces:

for dir in ???\(1\)/; do base=${dir%(*} for i in 1 2; do f=${base}_S1_L001_R${i}_001.fastq echo "mv ${base}/$f ${base}/$f.bak" echo "cat ${base}*/${f}* > ${base}/$f" done done 

Elimina los "ecos" cuando estés listo

No hay uso para ninguna herramienta de procesamiento de text que no sea cat , ya que todo lo que hace con el contenido del file es concatenarlas.

Comenzamos en RootDir. Supongo que en NNN (K), K ≤ 999999999, y K está escrito sin 0 de input. Construyo los patrones con ([0-9]) , ([0-9][0-9]) , etc. , para concatenar NNN (9) antes de NNN (10).

 pattern_prefix='[0-9][0-9][0-9]([1-9]' while [ ${#pattern_prefix} -le 13 ]; do # Iterate over the NNN(K) directory where K has a certain number of digits for dir in $pattern_prefix\); do if ! [ -d "$dir" ]; then break; fi base=${dir%\(*} target=$base/$base # If this is the first NNN(K) directory we meet for this NNN, create the base if [ ! -d "$target" ]; then mkdir "$target" cp -p "$base/"*.fastq "$target" fi # For each file in NNN(K), determine the target file and append for f in "$dir/"*.fastq; do stem=${f##*/}; stem=${f#*_*_} set -- "$target/"*_*_"$stem" cat "$f" >>"$1" done done pattern_prefix=$pattern_prefix'[0-9]' done 

Si entiendo la pregunta correctamente, quieres algo como esto:

 for D in ??? do [[ -d $D?* ]] || continue mkdir $D/$D for F in $D/* do cat $D*/$F > $D/$D/$F done done 

Eso supone que no hay espacios en el directory de nombres de files, y que todos los files duplicates aparecerán al less en el directory de 3 caracteres. Si puede tener un nombre de file que está solo en los directorys 111 (1), reemplace

  for F in $D/* 

con

  for F in $( find $D* -printf "%f\n" | sort -u ) 

por lo tanto, obtendrá una list de nombres únicos en 111, 111 (1), etc.