Как удалить часть строки, начинающуюся с косой черты - PullRequest
1 голос
/ 11 июня 2019

Как я хочу удалить все строки после косой черты, используя скрипт Perl?скажем, у меня есть входной файл, как показано ниже

Например:

hdkhehfkf/kfkjhoer
082734708/92740234

Я хочу получить вывод

hdkhehfkf
082734708

вот мой код

#!/usr/bin/perl
use strict;
use warnings;

my $file  = "file.sv";
my $dirname       = "../../../folder/";

open ( OUTFILE, ">uncompile_test.txt" );
main ();
close OUTFILE;


sub main {
   my @array;

   open( my $fh, "<", "$dirname/$file")
       or die "Failed to open file: $!\n";

   while(<$fh>) { 
       push @array, $_; 
   } 

   close $fh;

   print OUTFILE " ", @array;   
}

Ответы [ 3 ]

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

Для удаления последней косой черты в строке и всего, что после нее

$string =~ s{.*\K/.*}{};

, где \K отбрасывает все предыдущие совпадения, чтобы они не «потреблялись» (удаляются из строки во время сопоставления) и нам не нужно захватывать и возвращать первые .*.См. " Утверждения с обходом " в Расширенных паттернах в perlre для \K.Нам нужен этот первый .*, чтобы добраться до последнего /, по жадности *.

Чтобы удалить первый слеш в строке и все, что после нее

$string =~ s{/.*}{};

Я использую {}{} разделители, чтобы не использовать экранирование / в шаблонах.

Для вашего примера любой из этих работ.Они оба изменяют $string, который затем можно распечатать.

(Если речь идет о работе с путями, то я предлагаю использовать для этого несколько хороших модулей)


Вопрос был существенно отредактирован с добавлением кода

Чтобы выполнить это для каждой строки файла и сохранить вывод в другом файле

open my $fh_out, '>', $outfile or die "Can't open $outfile: $!";
open my $fh,     '<', $file    or die "Can't open $file: $!";

while (<$fh>) {
    print $fh_out s{.*\K/.*}{}r;
}

close $_ for $fh, $fh_out.

, где я использую модификатор /r, для " неразрушающего замещения ", с которым возвращается измененная строка (а оригинал остается без изменений), точно так же, как необходимо для печати непосредственно в файл.

Это удаляет последний / и все после него, первый случай выше;при необходимости измените на s{/.*}{}r.

Несколько комментариев к коду в вопросе

  • Используйте лексические файловые дескрипторы и три аргумента, открытые для выходного файла, и проверьте вызов open, так же, какВы хорошо делаете для входного файла (в подпрограмме)

  • Всегда передавайте подпрограмме все, что ей нужно, из внешнего кода;полагаться на подпрограмму, чтобы «видеть» переменные из окружающей области видимости, совершенно опасно.В вашем случае это будет означать

    sub process_file_to_output {          # find a suitable name
        my ($dir, $file, $fh_out) = @_;
        ...
    }
    

    , и вы будете называть его

    process_file_to_output($dirname, $file, $outfile_handle);
    

    , где $outfile_handle - это (лексический!) Дескриптор файла для выходного файла, если вы хотитечтобы открыть выходной файл в вызывающей программе, как в вопросе.

  • Наименование суб main не очень информативно.Выбор хороших имен для переменных и функций (и других элементов программы) оказывается очень важным в программировании.

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

Используйте оператор подстановки .

Выражение

'hdkhehfkf/kfkjhoer' =~ s|/.*||r

возвращает строку

'hdkhehfkf'
1 голос
/ 11 июня 2019

Вы можете попробовать разбить входную строку на /, а затем просто сохранить первую часть после разделения:

my $input = 'hdkhehfkf/kfkjhoer';   
my @parts = split /\//, $input;
print $parts[0];

Это печатает:

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