tr 명령은 $()에서 사용되고 변수에 저장되면 효과가 없습니다.

tr 명령은 $()에서 사용되고 변수에 저장되면 효과가 없습니다.

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*그렇지 않으면 (기본값은 공백, 탭, 줄 바꿈) 및 경로 이름 확장( , , ) 값을 기반으로 확장이 ?수행됩니다 [].

귀하의 경우 단어 분리가 발생하고 개행으로 구분된 각 요소를 개별적으로 가져와 최종적으로 공백으로 구분된 엔터티로 표시됩니다. 따옴표를 사용하면 단어 분할(및 경로 이름 확장)이 방지되므로 전체 확장이 단일 엔터티로 처리됩니다.

관련 정보