Использование bash для копирования содержимого строки в одном файле в определенное место символа в другом файле

Я новичок в bash и мне нужна помощь, чтобы скопировать строку 2 и далее из одного файла в определенную позицию (150 символов) в другом файле. Просматривая форум, я нашел способ включить конкретный текст, указанный в этой позиции:

sed -i 's / ^ (. {150}) / \ 1specifictextlisted /' destinationfile.txt

Однако я не могу найти способ скопировать в это содержимое из одного файла.

По сути, я работаю с этими двумя стартовыми файлами, и мне нужен следующий результат:

Содержание файла 1:

Sequence
AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT

Содержание файла 2:

chr2
tccccagcccagccccggccccatccccagcccagcctatccccagcccagcctatccccagcccagccccggccccagccccagccccggccccagccccagccccggccccagccccggccccatccccggccccggccccatccccggccccggccccggccccggccccggccccatccccagcccagccccagccccatccccagcccagccccggcccagccccagcccagccccagccacagcccagccccggccccagccccggcccaggcccagcccca

Желаемое выходное содержимое:

chr2 tccccagcccagccccggccccatccccagcccagcctatccccagcccagcctatccccagcccagccccggccccagccccagccccggccccagccccagccccggccccagccccggccccatccccggccccggccccatccccgAAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTTgccccggccccggccccggccccggccccatccccagcccagccccagccccatccccagcccagccccggcccagccccagcccagccccagccacagcccagccccggccccagccccggcccaggcccagcccca

Может ли кто-нибудь направить меня на правильный путь к достижению этого?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
247
3

Ответы 3

Для этого можно использовать awk:

awk 'NR==FNR{a=$2;next}{print $1, substr($2, 0, 149) "" a "" substr($2, 150)}' file1 file2

Объяснение:

# Total row number == row number in file
# This is only true when processing file1
NR==FNR {
    a=$2 # store column 2 in a variable 'a'
    next # do not process the block below
}
# Because of the 'next' statement above, this
# block gets only executed for file2
{
    # put 'a' in the middle of the second column and print it
    print $1, substr($2, 0, 149) "" a "" substr($2, 150)
}

Я предполагаю, что оба файла содержат только одну строку, как в вашем примере.


Обновлено: в комментариях вы сказали, что файлы на самом деле занимают две строки, в этом случае вы можете использовать следующий скрипт awk:

# usage: awk -f this_file.awk file1 file2

# True for the second line in each file
FNR==2 {
    # Total line number equals line number in file
    # This is only true while we are processing file1
    if (NR==FNR) {
        insert=$0 # Store the string to be inserted in a variable
    } else {
        # Insert the string in file1
        # Assigning to $0 will modify the current line
        $0 = substr($0, 0, 149) "" insert "" substr($0, 150)
    }
}

# Print lines of file2 (line 2 has been modified above)
NR!=FNR

Спасибо за этот пример. Прошу прощения, но форматирование файла, который я скопировал и вставил, изначально показывал содержимое файла 1 как одну строку, но на самом деле это две строки (отредактированные в основном сообщении). Аналогично, файл 2 содержит начальную строку с «Chr2» перед строкой последовательности ниже. Я ввел приведенный выше код с моими именами файлов вместо file1 и file2, но результат остается неизменным. Следует ли мне изменять что-либо еще в вашем коде, чтобы он работал правильно?

Hamishm 26.10.2018 03:43

Предполагая, что у вас есть только одна строка после заголовка последовательности, просто добавьте условие вроде !/^>/ перед открывающей фигурной скобкой в ​​последнем блоке и добавьте /^>/ после закрывающей фигурной скобки, чтобы пройти и распечатать заголовок последовательности.

tripleee 26.10.2018 09:49

Доброе утро! :) Извините, я спал. Я исправлю это, когда приду на работу

hek2mgl 26.10.2018 10:27

Вы можете использовать bash и читать по одному символу за раз из файла:

i=1
while read -n 1 -r; do
    echo -n "$REPLY"
    let i++
    if [ $i -eq 150 ]; then
        echo -n "AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT"
    fi
done < chr2 > destinationfile.txt

Это просто считывает символ, отображает его и увеличивает счетчик. Если счетчик равен 150, он повторяет вашу последовательность. Вы можете заменить эхо на cat file | tr -d '\n'. Просто убедитесь, что удалили все символы новой строки, как здесь, с tr. Вот почему я использую echo -n, поэтому он ничего не добавляет.

Спасибо за ответ. Я частично успешно протестировал ваш код здесь: i=1; while read -n 1 -r; do echo -n $REPLY; let i++; if [ $i -eq 150 ]; then echo -n "AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT"; fi;done < file2 > file1 Можно ли добиться этого без включения последовательности «AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT»? В нынешнем виде я могу добиться того же с sed -i 's/^(.{150})/\1AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT/' file2, но суть в том, чтобы взять его из строки 2 отдельного файла и не указывать в коде, поскольку я буду использовать это со многими файлами с разными последовательностями.

Hamishm 26.10.2018 04:09

вы можете удалить новую строку, добавив после нее | tr -d '\n'. Мой другой ответ тоже должен работать.

micke 26.10.2018 09:39

Если файл действительно огромен, а не всего 327 символов, вы можете использовать dd:

dd if=chr2 bs=1 count=150 status=none of=destinationfile.txt
tr -d '\n' < Sequence >> destinationfile.txt
dd if=chr2 bs=1 skip=150 seek=189 status=none of=destinationfile.txt

189 - это 150 + длина Sequence.

Должен ли последний параметр быть of=destinationfile.txt или вы хотите иметь два разных файла вывода?

tripleee 26.10.2018 09:46

@tripleee да, конечно, спасибо, что заметили это, и этот кот стал ненужным.

micke 26.10.2018 09:50
tr не может прочитать аргумент файла, вам нужно использовать перенаправление ввода. Но да, cat на одном файле всегда бесполезен.
tripleee 26.10.2018 09:50

Другие вопросы по теме