Как вставить строку (или символ) в другую строку в указанной позиции индекса в bash?

Есть похожие вопросы:

Но они просят решить какие-то конкретные проблемы, а не получить общее решение.

Как должна выглядеть функция в сценариях bash для вставки строки (или символа) в другую строку по указанному индексу? Решения, оптимизированные по производительности, приветствуются в первую очередь.

Примеры с входными параметрами и ожидаемыми результатами для требуемой функции/процедуры:

string: "/etc /bin"
string to insert: "/tmp "
position index to insert: 0 (beginning of string)
expected result: "/tmp /etc /bin"

string: "/etc /bin"
char to insert: "|"
position index to insert: 2
expected result: "/e|tc /bin"

string: "/tmp /etc"
string to insert: " /bin"
position index to insert: 9 (end of string)
expected result: "/tmp /etc /bin"

string: "/tmp /etc /bin"
string to insert: "[ ]"
position index to insert: 7
expected result: "/tmp /e[ ]tc /bin"

Связанный вопрос:


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

В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
2
0
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
cat insert_at_position.sh

#!/bin/bash

insert_at_position() {
    local input_string=$1; shift
    local insert_string=$1; shift
    local position=$1; shift
    local result = "${input_string:0:$position}$insert_string${input_string:$position}"
    echo "$result"
}

assert_equals() {
    local error_message=$1; shift
    local expected_result=$1; shift
    local actual_result=$1; shift

    if [ "$expected_result" != "$actual_result" ]; then
        printf "%s\n" "$error_message; Expected: $expected_result; Actual: $actual_result"
    fi
}

test_insert_at_position() {
    local test_line = "/etc /bin"
    local expected = "/e|tc /bin"
    local actual=$(insert_at_position "$test_line" "|" 2)
    assert_equals "test_insert_cursor_char-p2 failed" "$expected" "$actual"

    local test_line = "/tmp /etc"
    local expected = "/tmp /etc /bin"
    local actual=$(insert_at_position "$test_line" " /bin" 9)
    assert_equals "test_insert_cursor_char-p9 failed" "$expected" "$actual"

    local test_line = "/tmp /etc /bin"
    local expected = "/tmp /e[ ]tc /bin"
    local actual=$(insert_at_position "$test_line" "[ ]" 7)
    assert_equals "test_insert_cursor_char-p7 failed" "$expected" "$actual"

    local test_line = "/etc /bin"
    local expected = "/tmp /etc /bin"
    local actual=$(insert_at_position "$test_line" "/tmp " 0)
    assert_equals "test_insert_cursor_char-p0 failed" "$expected" "$actual"

    local test_line = "/etc /bin"
    local expected = "/tmp"
    local actual=$(insert_at_position "$test_line" "/tmp " 0)
    assert_equals "test_insert_cursor_char - here fail is expected" "$expected" "$actual"
}

test_insert_at_position

  • insert_at_position — функция, которая вставляет строку в строку по указанному индексу.
  • test_insert_at_position — юнит-тесты для этой функции
  • assert_equals — используется в test_insert_at_position, показывает сообщение об ошибке, если конкретный модульный тест не удался.

Ниже та же функция, но выполненная в виде процедуры с параметром out_result, содержащим результат. Для его вызова не требуется Command Substitution $() и связанное с ним создание подоболочки. Но тем не менее производительность этих функций примерно одинакова.

cat insert_at_position.sh

#!/bin/bash

assert_equals() {
    local error_message=$1; shift
    local expected_result=$1; shift
    local actual_result=$1; shift

    if [ "$expected_result" != "$actual_result" ]; then
        printf "%s\n" "$error_message; Expected: $expected_result; Actual: $actual_result"
    fi
}

insert_at_position() {
    local input_string=$1; shift
    local insert_string=$1; shift
    local position=$1; shift
    declare -n out_result=$1; shift
    out_result = "${input_string:0:$position}$insert_string${input_string:$position}"
}

test_insert_at_position() {
    test_line = "/etc /bin"
    expected = "/e|tc /bin"
    insert_at_position "$test_line" "|" 2 actual
    assert_equals "test_insert_cursor_char-p2 failed" "$expected" "$actual"

    test_line = "/tmp /etc"
    expected = "/tmp /etc /bin"
    insert_at_position "$test_line" " /bin" 9 actual
    assert_equals "test_insert_cursor_char-p9 failed" "$expected" "$actual"

    test_line = "/tmp /etc /bin"
    expected = "/tmp /e[ ]tc /bin"
    insert_at_position "$test_line" "[ ]" 7 actual
    assert_equals "test_insert_cursor_char-p7 failed" "$expected" "$actual"

    test_line = "/etc /bin"
    expected = "/tmp /etc /bin"
    insert_at_position "$test_line" "/tmp " 0 actual
    assert_equals "test_insert_cursor_char-p0 failed" "$expected" "$actual"

    test_line = "/etc /bin"
    expected = "/tmp"
    insert_at_position "$test_line" "/tmp " 0 actual
    assert_equals "test_insert_cursor_char - here fail is expected" "$expected" "$actual"
}

test_insert_at_position

Просто нарежьте строку var следующим образом:

str='abcd'
ins='O_o'

$ echo ${str:0:2} ${str:2}
ab cd

$ echo ${str:0:2}$ins${str:2}
abO_ocd

В этом решении «$string» и «$index_position» необходимо указать дважды. Я больше предпочитаю подход с функциями для уменьшения дублирования кода. Его проще использовать и проще поддерживать.

Anton Samokat 29.06.2024 22:49

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