Цикл For в цикле for для итерации файлов разных расширений - PullRequest
1 голос
/ 13 июня 2019

Скажем, у меня есть 20 разных файлов.Первые 10 файлов заканчиваются .counts.tsv, а остальные файлы заканчиваются .libsize.tsv.Для каждого .counts.tsv есть соответствующие .libsize.tsv файлы.Я хотел бы использовать цикл for для выбора обоих этих файлов и запустить скрипт R для этих двух типов файлов.Вот что я попробовал:

#!/bin/bash
arti='/home/path/tofiles'
for counts in ${arti}/*__counts.tsv ; do
    for libsize in "$arti"/*__libsize.tsv ; do
        Rscript score.R  ${counts} ${libsize}
 done;
done;

Вышеупомянутый скрипт оболочки перебирает файлы более 200 раз, тогда как у меня всего 20 файлов.Мне нужно, чтобы Rscript был выполнен 10 раз для обоих файлов.Любые предложения будут оценены.

Ответы [ 5 ]

3 голосов
/ 13 июня 2019

Создайте второе имя файла с помощью ${counts%counts.tsv} (удалить последнюю часть).

#!/bin/bash
arti='/home/path/tofiles'
for counts in ${arti}/*__counts.tsv ; do
    libsize="${counts%counts.tsv}libsize.tsv"
    Rscript score.R "${counts}" "${libsize}"
done

EDIT:
Менее безопасно пытаться сделать его единоличным. Если имена файлов без пробелов и переносов, вы можете рискнуть несчастным случаем с

echo ${arti}/*counts.tsv ${arti}/*.libsize.tsv | xargs -n2 Rscript score.R

и когда вам действительно повезет (без других файлов, кроме этих tsv-файлов в $arti), совершите банджи-джамп с

echo ${arti}/* | xargs -n2 Rscript score.R
3 голосов
/ 13 июня 2019

Я начал набирать ответ, прежде чем увидел ваш комментарий о том, что вы заинтересованы только в решении bash, и в любом случае оставлял сообщения на тот случай, если кто-то найдет этот вопрос в будущем и будет открыт для решения R.

Если бы я подходил к этому с нуля, я бы, вероятно, просто использовал функцию R, определенную в файле, которая принимает два имени файла, вместо того, чтобы возиться с вызовами system(), но это обеспечило бы желаемое поведение.

## Get a vector of files matching each extension
counts_names <- list.files(path = ".", pattern ="*.counts.tsv")
libsize_names <- list.files(path = ".", pattern ="*.libsize.tsv")

## Get the root names of the files before the extensions
counts_roots <- gsub(".counts.tsv$", "",counts_names)
libsize_roots <- gsub(".libsize.tsv$", "",libsize_names)

## Get only root names that have both file types
shared_roots <- intersect(libsize_roots,counts_roots)

## Loop through the shared root names and execute an Rscript call based on the two files
for(i in seq_along(shared_roots)){

  counts_filename <- paste0(shared_roots[[i]],".counts.tsv")
  libsize_filename <- paste0(shared_roots[[i]],".libsize.tsv")

  Command  <- paste("Rscript score.R",counts_filename,libsize_filename)
  system(Command)

}
1 голос
/ 13 июня 2019

Посмотрите, поможет ли нижеприведенное.

my_list = list.files("./Data")
counts = grep("counts.tsv", my_list, value=T)
libsize = grep("libsize.tsv", my_list, value=T)

for (i in seq(length(counts))){
  system(paste("Rscript score.R",counts[i],libsize[i]))
}
1 голос
/ 13 июня 2019

Вы пробовали list.files в базе? Это позволит вам использовать все файлы в папке.

arti='/home/path/tofiles'
for i in list.files(arti) {
  script
}
0 голосов
/ 14 июня 2019

Наконец,

Я попробовал следующее, и это помогло мне,

for sam in "$arti"/*__counts.tsv ; do
      filebase=$(basename $sam)
      samples=$(ls -1 ${filebase}|awk -F'[-1]' '{print $1}')
        Rscript score.R ${samples}__counts.tsv ${samples}__libsize.tsv
 done;

Для тех, кто ищет что-то похожее :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...