tr comando não tem efeito quando usado em $ () e salvo em uma variável

1

Se eu executo na CLI:

curl time.com | sed -n 's/.*href="\([^"]*\).*//p' | tr " " "\n"

então, como esperado, recebo uma lista de links higienizados da página para STDOUT , cada um em uma nova linha.

No entanto, quando eu salvar isso em uma variável e tentar echo , de um script.sh :

PAGE_LINKS=$(curl time.com | sed -n 's/.*href="\([^"]*\).*//p' | tr " " "\n")
echo $PAGE_LINKS

Eu obtenho todos os links em uma linha, separados por espaço. Então, como se o tr fosse ignorado.

Eu tentei várias coisas, incluindo algo como

HREFS=$(tr " " "\n" < "{PAGE_LINKS}")
echo $HREFS

Mas eu recebo file too long error. Alguma sugestão?

    
por Andrejs 23.10.2016 / 21:45

2 respostas

3

O problema não é tr , o problema reside em como você está produzindo a expansão da variável:

echo $PAGE_LINKS

Cite a expansão da variável:

echo "$PAGE_LINKS"

caso contrário, a expansão passará pela divisão de palavras de acordo com o valor de IFS (espaço, tabulação, nova linha por padrão) e expansão do nome do caminho ( * , ? , [] ).

No seu caso, a divisão de palavras está acontecendo, e cada elemento separado de nova linha está sendo tomado individualmente, e sendo mostrado como entidades separadas por espaço, finalmente. O uso de citações impedirá a divisão de palavras (e a expansão do nome do caminho), de modo que toda a expansão será tomada como uma entidade única.

    
por 23.10.2016 / 21:49
5

De acordo com a página bash man do $(command) construct:

Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting.

Portanto, tr não é o problema, mas bash exclui as novas linhas se elas estiverem à direita e remove outras novas linhas durante a divisão de palavras. Este é o comportamento documentado.

Eu acredito que você quer esse comportamento na maioria dos lugares. Se você tiver um arquivo com uma lista de nomes de arquivos, então:

for FILENAME in $(cat somefile)
do
     ...
done

Itera a lista de nomes de arquivos. Você não gostaria que as novas linhas em somefile atrapalhassem sua lista de palavras para usar como nomes de arquivos, e talvez até atrapalhassem seu loop de tarefas.

    
por 23.10.2016 / 21:53

Tags