Como devemos reproduzir a pilha em 'dirs -v'?

0

Eu tenho um arquivo cujo conteúdo é a saída de dirs -v , ou seja, nomes de caminho para diretórios:

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

Como você reproduziria a pilha de diretórios, ou seja, buscar o nome do caminho de cada diretório e aplicar pushd a ele, sem modificar o conteúdo do arquivo?

Aqui está um script que eu escrevi para esse propósito:

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

Mas quando eu corro

$ 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
...

Por que recebo os erros?

Obrigado.

    
por Tim 05.05.2018 / 02:01

1 resposta

1

O problema no seu script é que o programa awk define o primeiro campo para a cadeia vazia. Ao fazer isso, você não o exclui e, portanto, obtém um espaço (o separador de campos de saída padrão) como o primeiro caractere da variável de shell path . pushd não consegue encontrar os diretórios que você está alimentando devido ao espaço no início dos nomes, e é aí que você obtém os erros.

Em vez disso, você pode fazer algo como

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

O sed remove todos os espaços em branco e números iniciais do início da linha antes que read o leia.

Como discutido nos comentários: A substituição ${pathname/#\~\//$HOME/} só substituiria o til se ocorresse junto com / no início de $pathname . Para lidar com um ~ , você pode ter que adicionar uma substituição separada, ou algo parecido com

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

Se o arquivo de entrada foi criado usando dirs -l -p , o loop seria ainda mais simples:

while IFS= read -r pathname; do
    pushd "$pathname"
done <"$1"
    
por 05.05.2018 / 08:20