Объединение файлов в несколько подкаталогов соответствия

Мне нужно объединить файлы, основанные на имени подкаталога, в котором они находятся. В подкаталогах иногда есть дубликаты, а иногда нет. Структура файла выглядит следующим образом:

  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

Это значение имеет префикс номера 3 и R-номер, а concat – для сопоставления R # с переменным S-числом.

  1. Никаких конкатенаций не нужно делать с файлами в каталоге 633
  2. Все 3 файла R1 в 739 dirs должны быть объединены по порядку (739 сначала 739 (1) …)
  3. Выходу нужно будет перейти в субдир субдира (/ RootDir / 739/739 / *)
  4. В конце концов, каждый конечный выходной каталог будет иметь объединенный файл R1 и файл R2.

Я был бы очень признателен за любую помощь в правильном направлении. Также обратите внимание, что файлы .fastq – это просто файлы ASCII txt.

edit: Я видел эту несколько связанную запись , но не имел успеха в использовании кода из-за проблемы с несколькими совпадающими папками.

edit2: Ни одно из этих решений не работает для меня. Я медленно объединяю идеи, которые мне дали, и опубликую мое возможное решение здесь.

согласно вашему примеру, любая директория с «дубликатами» имеет дубликат, заканчивающийся на «(1)», поэтому:

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 

Удалите «эхо», когда вы будете готовы

Для любого инструмента обработки текста, отличного от cat , использовать нечего, поскольку все, что вы делаете с содержимым файла, – это их объединение.

Мы начинаем с RootDir. Я предполагаю, что в NNN (K), K ≤ 999999999, а K записывается без начального 0. Я строю шаблоны с ([0-9]) , ([0-9][0-9]) и т. Д. , чтобы объединить NNN (9) до 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 

Если я правильно понимаю вопрос, вы хотите что-то вроде этого:

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

Это не предполагает пробелов в каталоге имен файлов и что все дублированные файлы появятся, по крайней мере, в каталоге с тремя символами. Если у вас есть имя файла, которое находится только в 111 (1) каталогах, замените

  for F in $D/* 

с

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

поэтому вы получите список уникальных имен в 111, 111 (1) и т. д.