заменить строку после шаблона именем файла - PullRequest
1 голос
/ 13 февраля 2020

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

пример имени файла: GCF_000219725.1_ASM882v1 ___ Lalala_holae_9a5 c .gbf

раздел интересов в файлах:

DEFINITION  random_chacacters_including_spaces

желаемый вывод:

DEFINITION  GCF_000219725.1_ASM882v1___Lalala_holae_9a5c.gbf

Думал что-то вроде:

for f in *.gbf; do sed 's/DEFINITION  .*$/DEFINITION  "$f"/g'; done

который не работал

Спасибо

1 Ответ

1 голос
/ 14 февраля 2020

Ваша попытка содержит две ошибки:

  • она использует $f в выражении в одинарных кавычках (да, два " s также являются частями выражения в одинарных кавычках);
  • команде sed не предоставляется имя файла, в качестве аргумента которого используется $f;
  • , кроме того, в команде s не требуется флаг g.

Итак, что вы хотите сделать, это на самом деле следующее:

for f in *.gbf
do
  sed 's/DEFINITION  .*$/DEFINITION  '"$f"'/' "$f" > "$f.new"
done

, где скрипт sed представляет собой конкатенацию трех строк, которые, по порядку, заключаются в одинарные кавычки, в кавычках, в одинарных кавычках. Этот подход предотвращает расширение в единицах, заключенных в одинарные кавычки, в то же время разрешая его в частях, заключенных в двойные кавычки. В приведенном вами примере c разницы нет, но в общем случае рекомендуется заключать строки в одинарные кавычки (а команды sed являются строками), если только вам не нужно заключить их в двойные кавычки (см. Изучение bash Shell, 3-е издание, начало страницы 147 ). В последнем случае команда sed будет выглядеть следующим образом:

  sed "s/DEFINITION  .*$/DEFINITION  $f/" "$f" > "$f.new"

Более того, вам нужно поместить вывод куда-нибудь, например, в новый файл с именем $f.new (или вы можете использовать sed ' s -i опция, которая не POSIX, если я правильно помню).

...