Основные манипуляции со строками из имен файлов в bash - PullRequest
1 голос
/ 25 июня 2019

У меня есть несколько имен файлов в bash, которые я получил с помощью

$ ones=$(find SRR*pass*1*.fq)
$ echo $ones

SRR6301033_pass_1_trimmed.fq
SRR6301034_pass_1_trimmed.fq
SRR6301037_pass_1_trimmed.fq
...

Затем я преобразовал их в массив, чтобы я мог перебрать этот список и выполнить некоторые операции с именами файлов:

# convert to array
$ ones=(${ones// / })

и итерация:

for i in $ones; 
do
  fle=$(basename $i) 
  out=$(echo $fle | grep -Po '(SRR\d*)')
  echo "quants/$out.quant"
done

, которая производит:

quants/SRR6301033
SRR6301034
...
...
SRR6301220
SRR6301221.quant

Однако я хочу это:

quants/SRR6301033.quant
quants/SRR6301034.quant
...
...
quants/SRR6301220.quant
quants/SRR6301221.quant

Может кто-нибудь объяснить, почему яне работает и как это исправить?

1 Ответ

1 голос
/ 25 июня 2019

Почему вы хотите, чтобы это было сделано так сложно? Вы можете избавиться от всех ненужных обходных путей и просто использовать цикл for и встроенные методы расширения параметров, чтобы сделать это.

# Initialize an empty indexed array
array=()

# Start a loop over files ending with '.fq' and if there are no such files
# the *.fq would be un-expanded and checking it against '-f' would fail and
# in-turn would cause the loop to break out 

for file in *.fq; do
    [ -f "$file" ] || continue
    # Get the part of filename after the last '/' ( same as basename )
    bName="${file##*/}"
    # Remove the part after '.' (removing extension)
    woExt="${bName%%.*}"
    # In the resulting string, remove the part after first '_'
    onlyFir="${woExt%%_*}"
    # Append the result to the array, prefixing/suffixing strings 'quant'
    array+=( quants/"$onlyFir".quant )
done

Теперь распечатайте массив, чтобы увидеть результат

for entry in "${array[@]}"; do
    printf '%s\n' "$entry"
done

Способы вашей попытки могут потерпеть неудачу

  1. С ones=$(find SRR*pass*1*.fq) результаты сохраняются в переменной , а не в массиве . Переменная не может определить, является ли содержимое списком или одной строкой, разделенной пробелами
  2. При echo $ones, то есть раскрытии без кавычек, содержимое строки может быть разбито на слова. Вы можете не увидеть разницу, если у вас есть имена файлов с пробелами, если вы можете интерпретировать части имени файла как разные файлы
  3. Часть ${ones// / } не имеет смысла преобразовывать строку в массив, поскольку попытка использовать переменную без кавычек $ones сама по себе будет ошибочной
  4. for i in $ones; будет подвержен ошибкам по указанным выше причинам, имена файлов с пробелами могут интерпретироваться как отдельные файлы вместо одного.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...