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
*
그렇지 않으면 (기본값은 공백, 탭, 줄 바꿈) 및 경로 이름 확장( , , ) 값을 기반으로 확장이 ?
수행됩니다 []
.
귀하의 경우 단어 분리가 발생하고 개행으로 구분된 각 요소를 개별적으로 가져와 최종적으로 공백으로 구분된 엔터티로 표시됩니다. 따옴표를 사용하면 단어 분할(및 경로 이름 확장)이 방지되므로 전체 확장이 단일 엔터티로 처리됩니다.