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, 어쩌면 수행 루프가 엉망이 될 수도 있습니다.

답변2

문제는 아닙니다 tr. 문제는 변수 확장을 출력하는 방법에 있습니다.

echo $PAGE_LINKS

변수 확장을 인용해 보세요:

echo "$PAGE_LINKS"

IFS그렇지 않으면 확장은 (기본적으로 공백, 탭, 개행) 값에 따라 단어 분할과 경로 이름 확장( *, ?, [])을 거칩니다.

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

관련 정보