%20%D0%B8%20%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B8%20%D0%B2%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9.png)
Если я запускаю в CLI:
curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n"
затем, как и ожидалось, я получаю список очищенных ссылок со страницы на STDOUT
, каждую на новой строке.
Однако, когда я сохраняю это в переменную и пытаюсь получить echo
это из script.sh
:
PAGE_LINKS=$(curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n")
echo $PAGE_LINKS
Я получаю все ссылки в одну строку, разделенные пробелом. Так что как будто бы tr
игнорировалось.
Я пробовал много вещей, включая что-то вроде
HREFS=$(tr " " "\n" < "{PAGE_LINKS}")
echo $HREFS
Но потом получаю file too long
ошибку. Есть предложения?
решение1
Согласно bash
странице руководства по $(command)
конструкции:
Bash выполняет расширение, выполняя команду и заменяя подстановку команды стандартным выводом команды, при этом удаляются любые конечные символы новой строки. Встроенные символы новой строки не удаляются, но они могут быть удалены во время разделения слов.
Так что tr
это не проблема, а скорее bash
удаляет новые строки, если они заканчиваются, и удаляет любые другие новые строки во время разделения слов. Это поведение, как задокументировано.
Я думаю, что вы хотите такое поведение в большинстве мест. Если у вас есть файл со списком имен файлов, то:
for FILENAME in $(cat somefile)
do
...
done
Проходит по списку имен файлов. Вы не хотите, чтобы новые строки somefile
испортили ваш список слов для использования в качестве имен файлов, и, возможно, даже испортили ваш цикл for-do-done.
решение2
Проблема не в этом tr
, проблема в том, как вы выводите расширение переменной:
echo $PAGE_LINKS
Процитируйте расширение переменной:
echo "$PAGE_LINKS"
в противном случае расширение будет проходить через разбиение слов в соответствии со значением IFS
(пробел, табуляция, новая строка по умолчанию) и расширение имени пути ( *
, ?
, []
).
В вашем случае происходит разделение слов, и каждый элемент, отделенный новой строкой, берется по отдельности и в конечном итоге отображается как разделенные пробелом сущности. Использование кавычек предотвратит разделение слов (и расширение имени пути), поэтому все расширение будет восприниматься как одна сущность.