내용이 의 출력인 파일 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"