我们如何在“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程序将第一个字段设置为空字符串。通过这样做,您不会删除它,因此您会得到一个空格(默认输出字段分隔符)作为 shell 变量中的第一个字符pathpushd由于名称开头的空格,无法找到您要提供的目录,这就是您收到错误的地方。

相反,你可以做类似的事情

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"

相关内容