Функция
CREATE FUNCTION dbo.SplitToRows (@column varchar(100), @separator varchar(10))
RETURNS @rtnTable TABLE
(
ID int identity(1,1),
ColumnA varchar(max)
)
AS
BEGIN
DECLARE @position int = 0
DECLARE @endAt int = 0
DECLARE @tempString varchar(100)
set @column = ltrim(rtrim(@column))
WHILE @position<=len(@column)
BEGIN
set @endAt = CHARINDEX(@separator,@column,@position)
if(@endAt=0)
begin
Insert into @rtnTable(ColumnA) Select substring(@column,@position,len(@column)-@position)
break;
end
set @tempString = substring(ltrim(rtrim(@column)),@position,@endAt-@position)
Insert into @rtnTable(ColumnA) select @tempString
set @position=@endAt+1;
END
return
END
Использовать регистр
select * from dbo.SplitToRows('T14; p226.0001; eee; 3554;', ';')
Или просто выбрать с несколькими результирующими наборами
DECLARE @column varchar(max)= '1234; 4748;abcde; 324432'
DECLARE @separator varchar(10) = ';'
DECLARE @position int = 0
DECLARE @endAt int = 0
DECLARE @tempString varchar(100)
set @column = ltrim(rtrim(@column))
WHILE @position<=len(@column)
BEGIN
set @endAt = CHARINDEX(@separator,@column,@position)
if(@endAt=0)
begin
Select substring(@column,@position,len(@column)-@position)
break;
end
set @tempString = substring(ltrim(rtrim(@column)),@position,@endAt-@position)
select @tempString
set @position=@endAt+1;
END
Решение состоит в использовании $'string'
, например:
$ STR=$'Hello\nWorld'
$ echo "$STR"
Hello
World
Вот выдержка из страницы руководства Bash:
Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:
\a alert (bell)
\b backspace
\e
\E an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\" double quote
\nnn the eight-bit character whose value is the octal value
nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadecimal
value HH (one or two hex digits)
\cx a control-x character
The expanded result is single-quoted, as if the dollar sign had not
been present.
A double-quoted string preceded by a dollar sign ($"string") will cause
the string to be translated according to the current locale. If the
current locale is C or POSIX, the dollar sign is ignored. If the
string is translated and replaced, the replacement is double-quoted.
В моей системе (Ubuntu 17.10) ваш пример работает по желанию, как при вводе из командной строки (в sh
), так и при исполнении сценария sh
:
[bash]§ sh
$ STR="Hello\nWorld"
$ echo $STR
Hello
World
$ exit
[bash]§ echo "STR=\"Hello\nWorld\"
> echo \$STR" > test-str.sh
[bash]§ cat test-str.sh
STR="Hello\nWorld"
echo $STR
[bash]§ sh test-str.sh
Hello
World
Я думаю, это отвечает на ваш вопрос: он просто работает. (Я не пытался разобраться в деталях, например, в какой момент точно замена подписи символа новой строки для \n
происходит в sh
).
Однако я заметил, что этот же скрипт будет вести себя по-другому при выполнении с bash
и вместо этого распечатайте Hello\nWorld
:
[bash]§ bash test-str.sh
Hello\nWorld
Мне удалось получить желаемый результат с помощью bash
следующим образом:
[bash]§ STR="Hello
> World"
[bash]§ echo "$STR"
Обратите внимание на двойные кавычки вокруг $STR
. Это ведет себя одинаково, если сохраняется и выполняется как сценарий bash
.
Следующее также дает желаемый результат:
[bash]§ echo "Hello
> World"
A $ перед одинарными кавычками «...\n ...» следующим образом, однако двойные кавычки не работают.
$ echo $'Hello\nWorld'
Hello
World
$ echo $"Hello\nWorld"
Hello\nWorld
Я не эксперт по bash, но этот работал для меня:
STR1="Hello"
STR2="World"
NEWSTR=$(cat << EOF
$STR1
$STR2
EOF
)
echo "$NEWSTR"
Мне было легче форматировать тексты.
Эхо так девяносто и настолько чревато опасностями, что его использование должно привести к дампам ядра не менее 4 ГБ. Серьезно, проблемы эха были причиной того, что процесс стандартизации Unix, наконец, придумал утилиту printf
, устраняя все проблемы.
Итак, чтобы получить строку новой строки в строке:
FOO="hello
world"
BAR=$(printf "hello\nworld\n") # Alternative; note: final newline is deleted
printf '<%s>\n' "$FOO"
printf '<%s>\n' "$BAR"
Там! Нет SYSV против BSD echo madness, все становится аккуратно напечатанной и полностью переносимой поддержкой для escape-последовательностей C. Все, пожалуйста, используйте printf
сейчас и никогда не оглядывайтесь назад.
Я обнаружил, что -e
флаг элегантный и прямой
STR="Hello\nWorld"
echo -e $STR
#outputs
Hello
World
Если строка является результатом другой команды, я просто использую кавычки
indexes_diff=$(git diff index.yaml)
echo "$indexes_diff"
Проблема не в оболочке. Проблема на самом деле связана с командой echo
и отсутствием двойных кавычек вокруг интерполяции переменных. Вы можете попробовать использовать echo -e
, но это не поддерживается на всех платформах, и теперь одна из причин printf
теперь рекомендуется для переносимости.
Вы также можете попробовать и вставить новую строку непосредственно в свою оболочку скрипт (если скрипт - это то, что вы пишете), поэтому он выглядит как ...
#!/bin/sh
echo "Hello
World"
#EOF
или эквивалентно
#!/bin/sh
string="Hello
World"
echo "$string" # note double quotes!
$ STR='new
line'
$ printf '%s' "$STR"
new
line
Да, это означает запись Enter, где это необходимо в коде. new line
. \n ### A common way to represent a new line character.
\012 ### Octal value of a new line character.
\x0A ### Hexadecimal value of a new line character.
Но все они требуют «интерпретации» каким-либо инструментом ( POSIX printf ): echo -e "new\nline" ### on POSIX echo, `-e` is not required.
printf 'new\nline' ### Understood by POSIX printf.
printf 'new\012line' ### Valid in POSIX printf.
printf 'new\x0Aline'
printf '%b' 'new\0012line' ### Valid in POSIX printf.
И поэтому инструмент должен построить строку с новой строкой: $ STR="$(printf 'new\nline')"
$ printf '%s' "$STR"
new
line
$ STR=$'new\nline'
$ echo '6e65770a6c696e650a' | xxd -p -r
new
line
Или $ echo "new line" | sed 's/ \+/\n/g'
new
line
То, что я сделал по другим ответам, было
NEWLINE=$'\n'
my_var="__between eggs and bacon__"
echo "spam${NEWLINE}eggs${my_var}bacon${NEWLINE}knight"
# which outputs:
spam
eggs__between eggs and bacon__bacon
knight