Использование sed с переменной в шаблоне

С GNU grepи при условии, что имена файлов не содержат двоеточие или символы новой строки:

$ ls
bar     baz     foo     freeble quux
$ cat./*
# order: 3
# order: 2
# order: 1
# order: 4
# order: 5
$ grep -m1 -EH '^# order: [0-9]+$'./* | sort -n -k3 | cut -d: -f1
foo
baz
bar
freeble
quux
0
15.01.2020, 10:07
1 ответ

Добро пожаловать на сайт.

Я думаю, что вы смешиваете "подстановочные знаки" (, также известные как " оболочки " )с регулярными выражениями при использовании sed.

Очевидно, вы намерены заменить шаблон «подчеркивание, за которым следует любое количество букв и цифр, за которым следует .gc_corrected.bam» на _input.gc_corrected.bam. К сожалению, ваше выражение sedимеет два недостатка:

  • В вашей соответствующей части используется типичная для оболочки -нотация "шаблонного знака". Однако sedожидает здесь регулярное выражение, а в регулярных выражениях *означает не «любую строку из нуля или более символов», а «ноль или более повторений предыдущего символа».,так что ваше выражение заменит любой шаблон, состоящий из «ноль или более знаков подчеркивания, за которыми следует .gc_corrected.bam» заменой _input.gc_corrected.bam. Вот почему в вашем случае просто последнее подчеркивание перед суффиксом имени файла заменяется на _input.
  • Тем не менее, если у вас есть несколько символов подчеркивания в вашем фактическом имени файла, шаблон, соответствующий «строке, состоящей из любого количества символов», также будет включать символы подчеркивания, что может привести к нежелательному поведению при длине совпадающей строки. В частности, регулярные выражения являются жадными, и если они не составлены тщательно, вы можете в конечном итоге заменить всю _mESC_Rep_1_H3K27Acчасть имени файла на _input.

В вашем случае правильным регулярным выражением будет:

sed 's/_[^_]+\.gc_corrected\.bam/_input.gc_corrected.bam/g'

Это заменит строку, начинающуюся с символа подчеркивания _, за которым следует один или несколько символов , которые не являются символами подчеркивания ([^_]+), за которыми следует .gc_corrected.bam, с вашей заменой _input.gc_corrected.bam.

Обратите также внимание , что в регулярных выражениях .означает «любой одиночный символ» (, который в глобах оболочки будет представлен ?), поэтому, если вы хотите сопоставить литерал ., вы должны избежать его. Это, конечно, не обязательно в строке замены, так как , что не является регулярным выражением.

1
28.01.2020, 02:38

Теги

Похожие вопросы