Sed для редактирования заголовка с содержимым другого файла

Я пытаюсь заменить существующий заголовок в файле на основе содержимого другого файла.

File1 – names.in:

name1 name2 name3 name4 name5 

File2- Datafile.tsv:

 chr begin end genes genes genes genes genes 

File2 содержит больше строк, но я хочу заменить каждое вхождение genes строкой в ​​первой строке последовательными записями из file1 , чтобы заголовок стал:

 chr begin end name1.Corrected name2.Corrected name3.Corrected name4.Corrected name5.Corrected 

Я попробовал следующий скрипт:

 genenames=$1 sed -i -e "1s/\tgenes/\t$genenames\.Corrected/g" Datafile.tsv 

Но когда я запускаю его так:

 ./sed.sh names.in 

Я получаю вывод как:

 chr begin end .in.Corrected .in.Corrected .in.Corrected .in.Corrected .in.Corrected 

Я могу понять, что сценарий не читается со входа. Пожалуйста, предложите подходящее решение.

  • sed для замены пробелов в кавычках
  • Как сгруппировать группу строк на основе информации из первой строки?
  • Как удалить все CRLF в файле (не заменять LF)
  • Хотите, чтобы rsync некоторые файлы после того, как они были sedded
  • совпадение шаблона N раз
  • Как обменивать целые html-блоки в нескольких файлах с помощью sed
  • как использовать команду Diff, игнорируя текст в строке и получать непревзойденные данные на основе условия
  • Ошибка Sed, заменяющая частичную строку переменной
  • 3 Solutions collect form web for “Sed для редактирования заголовка с содержимым другого файла”

    пытаться

     for x in $(<names.in) do sed -i -s "s/ genes/ ${x}.Corrected/" Datafile.tsv done cat Datafile.tsv chr begin end name1.Corrected name2.Corrected name3.Corrected name4.Corrected name5.Corrected 
    • не используйте флаг /g который будет применяться ко всем вхождениям (вы хотите заменить один за другим)
    • замените мой ' ' на '\t'

    • $names.in будет расширяться до значения переменной имен (concatenate to .in), это, вероятно, будет расширяться до .in

    • $(< name.in ) читать файл name.in, перед выполнением команды и заменять содержимым файла (конец строки превращается в белый)

    более полная оболочка

     cat "$1" | while read x do sed -i -s "s/ genes/ ${x}.Corrected/" "$2" done 

    называется

      myscript.sh names.in Datafile.tsv 

    Если я правильно понял, вам нужно прочитать имена из file1 и заменить каждое вхождение genes строки последовательными записями из файла1, но только в первой строке файла2. Если это так, вы можете сделать это (предполагая, что у вас никогда не будет строки с genes в качестве подстроки, например, mygenes ):

     while read name do sed -i "1s/genes/$name.Corrected/" file2 done < file1 

    Кроме того, вы можете просто объединить содержимое файла1 и заменить все за один раз:

     names=$(perl -pe 's/\n/.Corrected /' file1) sed -i "1s/genes .*/$names/" file2 

    Ничто не сравнится с циклом while read во время обработки текста, но на всякий случай вы хотите обработать свой файл datafile.tsv только один раз :

     sed 's|\(.*\)|1s/genes/\1.Corrected/|' names.in | sed -f - datafile.tsv 

    Первый sed превращает names.in в sed-скрипт :

     1s/genes/name1.Corrected/ 1s/genes/name2.Corrected/ 1s/genes/name3.Corrected/ 1s/genes/name4.Corrected/ 1s/genes/name5.Corrected/ 

    который затем выполняется вторым sed .
    Если все столбцы ваших генов являются последовательными (например, в вашем примере ввода), вы также можете запустить:

     tr \\n \\t <names.in | \ sed -E 's|\t|.Corrected&|g;s|(.*).$|1s/genes.*genes/\1/|' | \ sed -f - datafile.tsv 

    который аналогичен первому, поскольку последний sed выполняет следующий сценарий sed :

     1s/genes.*genes/name1.Corrected name2.Corrected name3.Corrected name4.Corrected name5.Corrected/ 

    Обратите внимание, что они не будут редактировать ваш файл на месте. Для этого либо используйте sed с -i (если поддерживается), либо перенаправляйте > вывод, например, в newfile тогда mv newfile datafile.tsv

    Interesting Posts
    Linux и Unix - лучшая ОС в мире.