我有一个文件,其内容是 的输出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 变量中的第一个字符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"