"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プログラムが最初のフィールドを空の文字列に設定することです。これは削除しないため、シェル変数の最初の文字としてスペース(デフォルトの出力フィールド区切り文字)を取得します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"

関連情報