Регулярное выражение работает в терминале, но не в скрипте Perl

#regex #perl #text

#регулярное выражение #perl #текст

Вопрос:

Это связано с этим вопросом

Где выполняется комбинация всех строк, заканчивающихся символом обратной косой черты. Следующая команда Perl работает в терминале, но не в скрипте Perl:

 perl -i -p -e 's/\n//' input_file
  

В скрипте Perl я установил его таким образом, но он не работает:

 `perl -i -p -e 's/\n//' $input_file_path_variable`;
  

** Обновлено содержимое файла и используемый код

Введите содержимое файла следующим образом:

 foo bar 
bash 
baz
dude 
happy
  

Желаемый выходной контент:

 foo bar bash baz
dude happy
  

Текущий скрипт:

 #!/usr/bin/env perl 

use Getopt::Long;
use FindBin;
use File::Path;
use File::Copy;
use DirHandle;
use FileHandle;
use File::Basename;
use Env;
use File::Slurp;

my $dummy_file = "/wdir/dummy.txt";
my $file_content = read_file($dummy_file);
print "$file_contentn";
print "==============================================n"

my $ttest = $file_content =~ s/\n//;
print "$ttestn";
  

Текущий вывод

 foo bar 
bash 
baz
dude 
happy
==============================================
1

  

Комментарии:

1. Обратные ссылки действуют как строковые литералы, заключенные в двойные кавычки, и \ превращаются в строковые литералы, заключенные в двойные кавычки. /// Кроме того, у вас есть ошибка при внедрении кода. Это неправильный способ создания команды оболочки. См. String::ShellQuote . /// Наконец, почему вы используете обратные ссылки для программы, которая не выводит на стандартный вывод? Вы могли бы избежать необходимости использовать String::ShellQuote , используя форму с несколькими аргументами system .

2. @tobyink Да, могу ли я узнать правильный способ сделать это? Я попытался прочитать весь файл в переменную и применил ответ Оливера, но не смог получить желаемый результат.

3. Покажите нам свой код, ввод, который вы используете, и демонстрацию того, как он не работает.

4. @TLP Я в этом виноват, я обновил вопрос с помощью используемого ввода. Вы правы в своем предположении, и ваш ответ устранил мою проблему. Спасибо.

5. @tobyink Точка Зрения, взятая из-за того, что я не использую одну строку Perl в обратных ссылках в другом скрипте Perl, я понятия не имею, что это плохая идея. Подумал, что это самый быстрый способ сделать то, что я хочу, и изменить содержимое входного файла.

Ответ №1:

Кажется, я понял, в чем ваша проблема. Вам нужно, чтобы ваша замена совпадала несколько раз.

Вы работаете с этим однострочным:

 perl -i -p -e 's/\n//' input_file
  

Который заменит обратную косую черту и новую строку один раз на строку в файле, считываемом в построчном режиме. И теперь вы пытаетесь реализовать его внутри другой программы, где вы помещаете весь файл в переменную, как указано в вашем комментарии к другому ответу:

Я попытался прочитать весь файл в переменную и применил ваше решение, которое у меня не работает: мой $file_content = read_file($input_file_path_variable), а затем $file_content = ~ s / \ n//;

Это заменит только один раз. Первое совпадение в файле. Вам нужно добавить модификатор /g , чтобы сделать совпадение глобальным, как можно больше раз:

 $file_content =~ s/\n//g;
  

Я не уверен, как вы используете свой код, поскольку вы нам не показываете. Это затрудняет ответы на простые вопросы. Но если мои предположения верны, это решит вашу проблему.

Ответ №2:

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

 my $ttest = $file_content =~ s/\n//;
  

Во-первых, s/// оператору требуется a g в конце, чтобы это был глобальный поиск и замена, а не остановка после первой замены.

Во-вторых, $file_content =~ s/\n// не возвращает конечную строку; он изменяет строку на месте. (Так что это меняется $file_content .) В последних версиях Perl вы можете добавить r модификатор в конец, чтобы заставить его возвращать измененную строку.

Так что любой из них будет работать для вас:

 my $ttest = ( $file_content =~ s/\n//gr );
  

Или:

 ( my $ttest = $file_content ) =~ s/\n//g;
  

Полный скрипт, который выдает желаемый результат:

 #!/usr/bin/env perl 

use strict;
use warnings;
use File::Slurp;

my $file_content = read_file('/tmp/dummy.txt');

(my $ttest = $file_content) =~ s/\n//g;

print "$file_contentn";
print "==============================================n";
print "$ttestn";
  

Ответ №3:

В Perl вы должны написать:

 $input_file_variable =~ s/\n//;