Две, казалось бы, одинаковые строки с новыми строками - PullRequest
1 голос
/ 01 мая 2020

Я пытаюсь преобразовать список строк в кавычках, разделенных запятыми, в список строк, разделенных символами новой строки, используя bash и sed.

Вот пример того, что я делаю:

#!/bin/bash

comma_to_newline() {
  sed -En $'s/[ \t]*"([^"]*)",?[ \t]*/\\1\\\n/gp'
}

input='"one","two","three"'
expected="one\ntwo\nthree" 
result="$( echo "${input}" | comma_to_newline )"

echo "Expected: <${expected}>"
echo "Result: <${result}>"

if [ "${result}" = "${expected}" ]; then
  echo "EQUAL!"
else
  echo "NOT EQUAL!"
fi

И вывод, который я получаю:

Expected: <one
two
three>
Result: <one
two
three>
NOT EQUAL!

Я знаю, что это как-то связано с символами новой строки, но я не могу понять, что. Если я заменяю символы новой строки другой строкой, такой как XXX, она работает нормально, и bash сообщает, что строки равны.

Ответы [ 3 ]

1 голос
/ 02 мая 2020

По комментариям на мой вопрос мне удалось разобраться, что происходит. Я был так сосредоточен на том, чтобы придумать рабочее выражение sed и убедиться, что result был верным, что я не заметил, что строка expected неверна.

  1. Для использования \n новые строки в строке bash, вы должны использовать синтаксис $'one\ntwo\nthree' - см. Как получить новую строку в строке в sh? для других решений.
  2. Я разрабатывал против bash версии 3.2.57 (версия, которая поставляется с Ma c OS 10.14.6). При назначении переменной с помощью expected="one\ntwo\nthree" и ее повторном отображении они отображались как новые строки в консоли. В более новых версиях bash эти строки отображаются как экранированные, поэтому я предполагаю, что это ошибка, исправленная в более поздних версиях bash.
0 голосов
/ 01 мая 2020

В вашей функции возврата строки есть дополнительный символ новой строки \n.

Восьмеричный дамп

$echo '"one","two","three"' | sed -En $'s/[ \t]*"([^"]*)",?[ \t]*/\\1\\\n/gp' | od -c 
0000000   o   n   e  \n   t   w   o  \n   t   h   r   e   e  \n  \n
0000017
$echo "one\ntwo\nthree"  |  od -c 
0000000   o   n   e   \   n   t   w   o   \   n   t   h   r   e   e  \n
0000020
$

Также используйте echo -e

$echo "one\ntwo\nthree"  
one\ntwo\nthree
$echo -e "one\ntwo\nthree"  
one
two
three
$

со man страницы

-e включить интерпретацию backsla sh убегает

0 голосов
/ 01 мая 2020

Для диагностики, казалось бы, идентичных строк попробуйте объединить вывод diff рядом друг с другом в формате hexdump по одному символу на строку. Заменить:

else
  echo "NOT EQUAL!"
fi

... на:

else
    echo "NOT EQUAL!"
    diff -y \
    <(hexdump -v  -e '/1  "%_ad#  "' -e '/1 " _%_u\_\n"' <<< "${expected}") \
    <(hexdump -v  -e '/1  "%_ad#  "' -e '/1 " _%_u\_\n"' <<< "${result}")
fi
...