Пример printf в bash не создает новую строку - PullRequest
23 голосов
/ 20 апреля 2010

Работа с printf в скрипте bash, добавление без пробелов после "\n" не создает новую строку, тогда как добавление пробела создает новую строку, т.е. г .:

  1. Нет пробела после "\n"

    NewLine=`printf "\n"`
    echo -e "Firstline${NewLine}Lastline"
    

    Результат:

    FirstlineLastline
    
  2. Пробел после "\n "

    NewLine=`printf "\n "`
    echo -e "Firstline${NewLine}Lastline"
    

    Результат:

    Firstline
     Lastline
    

Вопрос: Почему 1. не создается следующий результат:

Firstline 
Lastline

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

Отредактировано: При использовании echo вместо printf я получаю ожидаемый результат, но почему printf работает по-другому?

    NewLine=`echo "\n"`
    echo -e "Firstline${NewLine}Lastline"

Результат:

    Firstline
    Lastline

Ответы [ 7 ]

27 голосов
/ 20 апреля 2010

Оператор backtick удаляет завершающие новые строки. См. 3.4.5. Подстановка команд при http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

Примечание по отредактированному вопросу

Сравните:

[alvaro@localhost ~]$ printf "\n"

[alvaro@localhost ~]$ echo "\n"
\n
[alvaro@localhost ~]$ echo -e "\n"


[alvaro@localhost ~]$

Команда echo не рассматривает \n как символ новой строки, если вы не скажете ему сделать это:

NAME
       echo - display a line of text
[...]
       -e     enable interpretation of backslash escapes

POSIX 7 определяет это поведение здесь :

[...] со стандартным выводом команды, удаляющей последовательности из одного или нескольких символов в конце подстановки

4 голосов
/ 05 сентября 2010
$ printf -v NewLine "\n"
$ echo -e "Firstline${NewLine}Lastline"

Firstline
Lastline

$ echo "Firstline${NewLine}Lastline"
Firstline
Lastline
3 голосов
/ 18 января 2017

Может быть, люди придут сюда с той же проблемой, что и я: эхо \ n внутри кода, обернутого в backsticks. Небольшой совет:

printf "astring\n"
# and 
printf "%s\n" "astring" 
# both have the same effect.
# So... I prefer the less typing one

Краткий ответ:

# Escape \n correctly !

# Using just: printf "$myvar\n" causes this effect inside the backsticks:
printf "banana
"

# So... you must try \\n  that will give you the desired 
printf "banana\n"

# Or even \\\\n if this string is being send to another place 
# before echoing,

buffer="${buffer}\\\\n printf \"$othervar\\\\n\""

Одна распространенная проблема заключается в том, что если вы делаете внутри кода:

echo 'Tomato is nice'

при окружении бэкстиками выдает ошибку

command Tomato not found.

Обходной путь - добавить другое echo -e или printf

printed=0

function mecho(){
  #First time you need an "echo" in order bash relaxes.
  if [[ $printed == 0 ]]; then
    printf "echo -e $1\\\\n"
    printed=1
  else
    echo -e "\r\n\r$1\\\\n"
  fi
}

Теперь вы можете отлаживать свой код, выполняя подсказку просто:

(prompt)$  `mySuperFunction "arg1" "etc"`

Вывод будет приятно

 mydebug: a value
 otherdebug: whathever appended using myecho
 a third string

и внутренняя отладка с помощью

mecho "a string to be hacktyped"
3 голосов
/ 20 апреля 2010

Ваша отредактированная версия echo помещает буквальную обратную косую черту в переменную $NewLine, которая затем интерпретируется вашим echo -e. Если вы сделали это вместо:

NewLine=$(echo -e "\n")
echo -e "Firstline${NewLine}Lastline"

Ваш результат будет таким же, как в случае № 1. Чтобы заставить этот работать так, вам нужно было бы избежать обратной косой черты и поместить все это в одинарные кавычки:

NewLine=$(printf '\\n')
echo -e "Firstline${NewLine}Lastline"

или двойной выход из нее:

NewLine=$(printf "\\\n")

Конечно, вы можете просто использовать printf напрямую или установить значение NewLine следующим образом:

printf "Firstline\nLastline\n"

или

NewLine=$'\n'
echo "Firstline${NewLine}Lastline"    # no need for -e
3 голосов
/ 20 апреля 2010

Похоже, BASH удаляет завершающие символы новой строки. например,

NewLine=`printf " \n\n\n"`
echo -e "Firstline${NewLine}Lastline"
Firstline Lastline

NewLine=`printf " \n\n\n "`
echo -e "Firstline${NewLine}Lastline"
Firstline


 Lastline
1 голос
/ 21 апреля 2010

Нам не нужны «echo» или «printf» для создания переменной NewLine:

NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"
0 голосов
/ 20 апреля 2010

Работает нормально, если вы добавите "\ r"

$ nl=`printf "\n\r"` && echo "1${nl}2"
1
2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...