Многострочная строка с дополнительным пространством (сохраненный отступ)

Я хочу записать некоторые предварительно определенные тексты в файл со следующим:

text="this is line one\n
this is line two\n
this is line three"

echo -e $text > filename

Я ожидаю что-то вроде этого:

this is line one
this is line two
this is line three

Но получилось:

this is line one
 this is line two
 this is line three

Я уверен, что после каждого \n нет пробела, но как выходит дополнительное пространство?

Ответ 1

Эредок звучит для этого удобнее. Он используется для отправки нескольких команд в программу интерпретатора команд, например ex или cat

cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

Строка после << указывает, где остановиться.

Чтобы отправить эти строки в файл, используйте:

cat > $FILE <<- EOM
Line 1.
Line 2.
EOM

Вы также можете сохранить эти строки в переменной:

read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM

Это сохраняет строки в переменной с именем VAR.

При печати запомните кавычки вокруг переменной, иначе вы не увидите символы новой строки.

echo "$VAR"

Более того, вы можете использовать отступы, чтобы они выделялись в вашем коде. На этот раз просто добавьте - после << чтобы закладки не появлялись.

read -r -d '' VAR <<- EOM
    This is line 1.
    This is line 2.
    Line 3.
EOM

Но тогда вы должны использовать табуляции, а не пробелы, для отступа в вашем коде.

Ответ 2

Если вы пытаетесь получить строку в переменной, другой простой способ выглядит примерно так:

USAGE=$(cat <<-END
    This is line one.
    This is line two.
    This is line three.
END
)

Если вы введете строку с вкладками (т.е. '\ t'), отступ будет удален. Если вы отступаете с пробелами, отступ будет оставлен.

ПРИМЕЧАНИЕ. Важно отметить, что последняя закрывающая скобка находится на другой строке. Текст END должен отображаться на отдельной строке.

Ответ 3

echo добавляет пробелы между переданными ему аргументами. $text подвержен переменному расширению и разбиению слов, поэтому ваша команда echo эквивалентна:

echo -e "this" "is" "line" "one\n" "this" "is" "line" "two\n"  ...

Вы можете увидеть, что пространство будет добавлено до "this". Вы можете удалить символы новой строки и указать $text, чтобы сохранить символы новой строки:

text="this is line one
this is line two
this is line three"

echo "$text" > filename

Или вы можете использовать printf, который является более надежным и портативным, чем echo:

printf "%s\n" "this is line one" "this is line two" "this is line three" > filename

В bash, который поддерживает расширение фигурной скобки, вы можете даже сделать:

printf "%s\n" "this is line "{one,two,three} > filename

Ответ 4

в bash script выполняются следующие работы:

#!/bin/sh

text="this is line one\nthis is line two\nthis is line three"
echo $text > filename

альтернативный вариант:

text="this is line one
this is line two
this is line three"
echo "$text" > filename

cat filename дает:

this is line one
this is line two
this is line three

Ответ 5

Я нашел больше решений, так как я хотел, чтобы каждая строка имела правильный отступ:

  1. Вы можете использовать echo:

    echo    "this is line one"   \
        "\n""this is line two"   \
        "\n""this is line three" \
        > filename
    

    Это не работает, если вы ставите "\n" непосредственно перед \ в конце строки.

  2. Кроме того, вы можете использовать printf для лучшей переносимости (у меня было много проблем с echo):

    printf '%s\n' \
        "this is line one"   \
        "this is line two"   \
        "this is line three" \
        > filename
    
  3. Еще одно решение может быть:

    text=''
    text="${text}this is line one\n"
    text="${text}this is line two\n"
    text="${text}this is line three\n"
    printf "%b" "$text" > filename
    

    или же

    text=''
    text+="this is line one\n"
    text+="this is line two\n"
    text+="this is line three\n"
    printf "%b" "$text" > filename
    
  4. Другое решение достигается путем смешивания printf и sed.

    if something
    then
        printf '%s' '
        this is line one
        this is line two
        this is line three
        ' | sed '1d;$d;s/^    //g'
    fi
    

    Реорганизовать код, отформатированный таким образом, нелегко, поскольку вы жестко закодировали уровень отступа в коде.

  5. Можно использовать вспомогательную функцию и некоторые приемы подстановки переменных:

    unset text
    _() { text="${text}${text+
    }${*}"; }
    # That an empty line which demonstrates the reasoning behind 
    # the usage of "+" instead of ":+" in the variable substitution 
    # above.
    _ ""
    _ "this is line one"
    _ "this is line two"
    _ "this is line three"
    unset -f _
    printf '%s' "$text"
    

Ответ 6

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

read -r -d '' my_variable << \
_______________________________________________________________________________

String1
String2
String3
...
StringN
_______________________________________________________________________________

Количество подчеркиваний одинаково (здесь 80) в обоих случаях.

Ответ 7

это будет работать, если вы поставите его как показано ниже:

AA='first line
\nsecond line 
\nthird line'
echo $AA
output:
first line
second line
third line

Ответ 8

Что если вы читаете многострочный вывод из скрипта?

Я пытался сделать что-то вроде...

OUTPUT экспорта = $ (ls -Fla/тонну)

... и когда я делаю...

echo $ OUTPUT

... это довольно некрасиво...

всего 36 drwxrwxrwt 9 корневой корень 4096 апр. 5 20:09./drwxr-xr-x 24 корневой корень 4096 апр. 3 06:46../drwxrwxrwt 2 корневой корень 4096 18 марта 18:26.ICE-unix/drwxrwxrwt 2 корневой корень 4096 18 марта 18:26.Test-unix/drwxrwxrwt 2 root root 4096 Mar 18 18:26.X11-unix/drwxrwxrwt 2 root root 4096 18 марта 18:26.XIM-unix/drwxrwxrwt 2 root root 4096 18 марта 18: 26.font-unix/drwx------ 3 корневой корень 4096 18 марта 18:26 systemd-private-21ccc8c939c9415fb522b60ed197c724-systemd-resolved.service-SnudvR/drwx------ 3 корневой корень 4096 18 марта 18:26 systemd-private-21ccc8c939c9415fb722606077 Systemd-timesyncd.service-C49grY/

Я пытаюсь запустить скрипт, сохранить отформатированный текст в переменную, а затем передать его в SMS в AWS, но преобразование в переменную, похоже, разрушает форматирование.

Есть идеи?