заменить / заменить список подстрок в списке имен файлов в bash (с помощью awk?) - PullRequest
0 голосов
/ 26 апреля 2018

Я обнаружил, что в некоторых из моих> 100 000 имен файлов мой разделитель _ также появляется на непредвиденных позициях и портит обработку. Поэтому я хотел бы заменить _ в этих файлах. Они все в одной папке. Я пытался использовать переменную awk FILENAME, но я не знаю, как ее изменить, чтобы изменить само имя файла. Полные имена файлов, например,

mg.reads.per.gene_Putative@polyhydroxyalkanoic@acid@system@protein@(PHA_gran_rgn)_A1.tsv   
mg.reads.per.gene_Phage@regulatory@protein@Rha@(Phage_pRha)_A1.tsv 
...

В общем, первый и последний _ должны быть там, все дополнительные должны быть заменены. Примечание: дополнительные не всегда в скобках. Я сгенерировал список с этими проблемными подстроками в имени файла с именем problems.txt:

Putative@polyhydroxyalkanoic@acid@system@protein@(PHA_gran_rgn)
Phage@regulatory@protein@Rha@(Phage_pRha)
Phage@tail@protein@(Tail_P2_I)
Phd_YefM
pheT_bact:@phenylalanine--tRNA@ligase%2C@beta@subunit
...

и здесь также хотелось бы использовать @ в качестве необычного символа для получения:

mg.reads.per.gene_Putative@polyhydroxyalkanoic@acid@system@protein@(PHA@gran@rgn)_A1.tsv    
mg.reads.per.gene_Phage@regulatory@protein@Rha@(Phage@pRha)_A1.tsv 
...

как использовать этот список в качестве входных данных для изменения только тех имен файлов, которые соответствуют записям в списке? Я попытался это, чтобы обратиться к файлам в папке и изменить часть имени файла (псевдокод awk):

for sample_files in $(find . -mindepth 1 -maxdepth 1 -type f)
do  
  awk '{if ("problem_record" ~ FILENAME); 
  gsub(/_/,/@/, substring(FILENAME))); print}' problems.txt $sample_files > $sample_files
done

но я не могу указать, что мне нужны только изменения в области, охватываемой записями "problem_record". Я тоже не знаю, как указать вывод

1 Ответ

0 голосов
/ 26 апреля 2018

Вот чистое решение для bash:

#!/bin/bash

# Loop over all files in the current directory
for i in *; do

  # Extract the part before the first _
  head="${i%%_*}"

  # Get the rest of the string
  tail="${i#*_}"

  # Extract the part after the last _
  rhead="${tail##*_}"

  # Extract the "middle" portion
  rtail="${tail%_*}"

  # Substitute _ with @ in the "middle"
  fixedrtail="${rtail//_/@}"

  # Rename files
  #echo -e "Renaming \"$i\" to \"$head_${fixedrtail}_$rhead\""
  mv $i "${head}_${fixedrtail}_${rhead}"
done

Это берет все файлы в текущем каталоге и переименовывает их так, что все _, кроме первого и последнего, заменяются на @. Он использует множество расширений параметров, о которых вы можете прочитать здесь .

...