"dirs -v"에서 스택을 어떻게 재현할 수 있나요?

"dirs -v"에서 스택을 어떻게 재현할 수 있나요?

내용이 의 출력인 파일 dirs -v, 즉 디렉토리의 경로 이름이 있습니다.

 0  ~/program_files/OS/dirs/recentVisitedDirs
 1  ~/cs/security/computer security/OS security/user management/programs
 ...

pushd파일의 내용을 수정하지 않고 어떻게 디렉토리 스택을 재생성할 수 있습니까? 즉, 각 디렉토리의 경로 이름을 가져와 적용합니까 ?

이 목적을 위해 제가 작성한 스크립트는 다음과 같습니다.

while read line; do
    pathname="$(awk '{ $1=""; print}'<<< $line )"
    path="${pathname//\~/$HOME}"
    pushd "$path"
done < "$1"

하지만 내가 달릴 때

$ myscript ./myfile
/home/t/bin/myscript: line 13: pushd:  /home/t/program_files/OS/dirs/recentVisitedDirs: No such file or directory
/home/t/bin/myscript: line 13: pushd:  /home/t/cs/security/computer security/OS security/user management/programs: No such file or directory
...

이러한 오류가 발생하는 이유는 무엇입니까?

감사해요.

답변1

스크립트의 문제는 awk프로그램이 첫 번째 필드를 빈 문자열로 설정한다는 것입니다. 이렇게 하면 이를 제거하지 않으므로 쉘 변수의 첫 번째 문자로 공백(기본 출력 필드 구분 기호)을 얻게 됩니다 path. pushd오류가 발생하는 이름 시작 부분의 공백으로 인해 제공하려는 디렉터리를 찾을 수 없습니다.

대신 다음과 같은 작업을 수행할 수 있습니다.

sed 's/^[[:blank:]]*[0-9]*[[:blank:]]*//' <"$1" |
while IFS= read -r pathname; do
    pushd "${pathname/#\~\//$HOME/}"
done

읽기 전에 sed줄 시작 부분의 모든 초기 공백과 숫자가 제거됩니다.read

설명에서 설명한 대로 교체는 의 시작 부분에 와 함께 나타나는 ${pathname/#\~\//$HOME/}물결표만 대체합니다 . 별도의 항목을 처리하려면 별도의 대체 항목을 추가해야 할 수도 있습니다./$pathname~

case "$pathname" in
    "~")   pathname=$HOME ;;
    "~/"*) pathname=${pathname/#\~/$HOME} ;;
esac
pushd "$pathname"

다음을 사용하여 입력 파일을 생성하면 루프가 더 간단해집니다 dirs -l -p.

while IFS= read -r pathname; do
    pushd "$pathname"
done <"$1"

관련 정보