Как обработать имя файла из нескольких каталогов по Perl? - PullRequest
0 голосов
/ 08 июля 2019

Я использую Perl для упорядочения нескольких файлов .txt из разных каталогов.

У меня есть папки: A_1, A_2, A_3, ...
Файлсписки в папке A_1:
V_3_C_1.txt, V_3_C_2.txt, ..., V_3_C_38.txt и
V_1_C_1.txt, V_1_C_2.txt, ..., V_1_C_38.txt.по некоторым причинам файлы в папке A_1 могут быть сгруппированы в V_3 и V_1

Список файлов в папке A_2:
V_4_C_1.txt, V_4_C_2.txt,..., V_4_C_38.txt и
V_1_C_1.txt, V_1_C_2.txt, ..., V_1_C_38.txt.
файлы в папке A_2 можно сгруппировать в V_4 и V_1

Я собираюсь запустить систему (Java-программу) на Perl.Первое, что я собираюсь извлечь часть имени файла.Мои коды здесь:

my % seen;
my @dups;
my @unqie;

my $file_list = '/home/V/Documents/A_1';
opendir (DIR, $file_list) or die "Could not open $file_list\n";  
my @vcf_files = grep (/\.txt$/, readdir DIR);  

for my $line (@vcf_files) {
    my @vcf_index = split ('_' , $line);
    my @dups = grep ++$seen{$_} ==2, $vcf_index[1]; #get the unique values, for example in `A_1` folder, I try to extract 3 and 1 from `V_3` and `V_1  `  
    push @unqie, @dups; #push into array for next steps. 

    for (my $i=1; $i <=38; $i++) {
        my @external_command = (
            "java",
            "-jar",
            "/home/V/Documents/beagle.03Jul19.b33.jar",
            "gt=/home/V/Documents/A_1/V_".$unqie[0]."_C_".$i."\.txt",
            "out = .............."
        );
        my @external_command_1 = (
            "java",
            "-jar",
            "/home/V/Documents/beagle.03Jul19.b33.jar",
            "gt=/home/V/Documents/A_1/V_".$unqie[1]."_C_".$i."\.txt",  
            "out = .............. "
        );

        my $out = system(@external_command);
        my $out_1 = system(@external_command_1);
        # ....
    }
}

Для этого кода Java-программа работает хорошо.Однако, когда я добавляю цикл для этого кода, я хочу обработать папку одну за другой: открыть A_1, затем запустить java, закончить.Откройте A_2, затем запустите java, закончите ... откройте A_3, ........

for (my $j=1; $j<=2; $j++) {
    my $file_list = '/home/v/Documents/A_' . $j;
    opendir (DIR, $file_list) or die "Could not open $file_list\n";

    my @vcf_files = grep (/\.txt$/, readdir DIR);
    for my $line (@vcf_files) {
        my @vcf_index = split ('_' , $line);
        my @dups = grep ++$seen{$_} ==2, $vcf_index[1];
        push @unqie, @dups;

        for (my $i=1; $i <=38; $i++) {
            my @external_command = (
                "java",
                "-jar",
                "/home/V/Documents/beagle.03Jul19.b33.jar",
                "gt=/home/V/Documents/A_.$j/V_" . $unqie[0] . "_C_".$i."\.txt",  
                "out = .............."
            );
            my @external_command_1 = (
                "java",
                "-jar",
                "/home/victor/Documents/beagle.03Jul19.b33.jar",
                "gt=/home/V/Documents/A_.$j/V_".$unqie[1]."_C_".$i."\.txt",  
                "out = .............."
            );

            my $out = system(@external_command);
            my $out_1 = system(@external_command_1);
        }
    }
}

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

Может кто-нибудь помочь мне разобраться?Спасибо

1 Ответ

2 голосов
/ 09 июля 2019

Хороший подход к отладке подобных вещей - не запускать программы, а распечатывать командную строку, чтобы увидеть, что будет выполняться.

То есть замените эти строки:

my $out = system(@external_command);
my $out_1 = system(@external_command_1);

с этими:

print "@external_command\n";
print "@external_command_1\n";

(Кстати, похоже, что в вашем исходном коде есть неправильное понимание - system() возвращает код завершения процесса, а не вывод.)

Запустив это, ваш первый код выдаст мне вывод, подобный следующему:

java -jar /home/V/Documents/beagle.03Jul19.b33.jar gt=/home/V/Documents/A_1/V__C_1.txt out = ..............
java -jar /home/V/Documents/beagle.03Jul19.b33.jar gt=/home/V/Documents/A_1/V__C_1.txt out = ..............
java -jar /home/V/Documents/beagle.03Jul19.b33.jar gt=/home/V/Documents/A_1/V__C_2.txt out = ..............
java -jar /home/V/Documents/beagle.03Jul19.b33.jar gt=/home/V/Documents/A_1/V__C_2.txt out = ..............

Это мне не подходит.Смотрите, у вас есть такие вещи, как V__C_1.txt.Похоже, что между двумя подчеркиваниями отсутствует значение.Он исходит из этого кода:

"gt=/home/V/Documents/A_.$j/V_".$unqie[0]."_C_".$i."\.txt"

И этого кода:

"gt=/home/V/Documents/A_.$j/V_".$unqie[1]."_C_".$i."\.txt"

Так что, похоже, @unqie никогда не получает никаких данных.И это означает, что @dup также никогда не получает никаких данных.

Запуск вашей второй программы дает следующий вывод:

java -jar /home/V/Documents/beagle.03Jul19.b33.jar gt=/home/V/Documents/A_.1/V__C_1.txt out = ..............
java -jar /home/victor/Documents/beagle.03Jul19.b33.jar gt=/home/V/Documents/A_.1/V__C_1.txt out = ..............

Это имеет ту же проблему, что и первая версия (предположительно)вызвано тем же самым), но у этого также есть это - A_.1.Это происходит из этого кода:

"gt=/home/V/Documents/A_.$j/V_" . $unqie[0] . "_C_".$i."\.txt",

В частности, от A_.$j.Я думаю, что вы имели в виду эту точку как оператор конкатенации, но поскольку она находится внутри строки в кавычках, она просто интерпретируется как точка.Это легко исправить, просто удалив точку.

Трудно быть намного более полезным, так как я не совсем понимаю, что вы пытаетесь сделать, и переменные типа %seen и @unqie просто появляютсясуществование без объяснения причинНо вот еще несколько советов.

  • Добавьте use strict и use warnings.И исправьте проблемы, которые они обнаружат.
  • for (my $j=1; $j<=2; $j++), вероятно, яснее записать как for my $i (1 .. 2)
  • Использовать лексическую переменную для дескрипторов каталогов (opendir my $dir_h, $file_list и readdir $dir_h)
  • Первый аргумент split - это регулярное выражение (split /_/, $line)
  • Переменные раскрываются в строки в двойных кавычках

Если вы расширяете то, что пытаетесьчтобы сделать, то мы, вероятно, можем больше помочь.

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