El comando tr no tiene ningún efecto cuando se usa en $() y se guarda en una variable

El comando tr no tiene ningún efecto cuando se usa en $() y se guarda en una variable

Si ejecuto en la CLI:

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

luego, como era de esperar, obtengo una lista de enlaces desinfectados desde la página a STDOUT, cada uno en una nueva línea.

Sin embargo, cuando guardo eso en una variable e intento hacerlo echodesde script.sh:

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

Obtengo todos los enlaces en una línea, separados por espacios. Como si trfuera ignorado.

Probé varias cosas, incluyendo algo como

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

Pero luego aparece file too longun error. ¿Alguna sugerencia?

Respuesta1

Según la bashpágina de manual de la $(command)construcción:

Bash realiza la expansión ejecutando el comando y reemplazando la sustitución del comando con la salida estándar del comando, eliminando las nuevas líneas finales. Las nuevas líneas incrustadas no se eliminan, pero pueden eliminarse durante la división de palabras.

Entonces tr, no es el problema, sino que bashelimina las nuevas líneas si están al final y elimina cualquier otra nueva línea durante la división de palabras. Este es el comportamiento documentado.

Creo que deseas este comportamiento en la mayoría de los lugares. Si tiene un archivo con una lista de nombres de archivo, entonces:

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

Itera sobre la lista de nombres de archivos. No querrás que las nuevas líneas somefilearruinen tu lista de palabras para usar como nombres de archivos, y tal vez incluso arruinen tu bucle for-do-done.

Respuesta2

El problema no es tr, el problema reside en cómo genera la expansión de la variable:

echo $PAGE_LINKS

Cite la expansión variable:

echo "$PAGE_LINKS"

de lo contrario, la expansión pasará por la división de palabras según el valor de IFS(espacio, tabulación, nueva línea de forma predeterminada) y la expansión del nombre de ruta ( *, ?, []).

En su caso, se produce la división de palabras y cada elemento separado por nueva línea se toma individualmente y finalmente se muestra como entidades separadas por espacios. El uso de comillas evitará la división de palabras (y la expansión de la ruta), por lo que toda la expansión se tomará como una sola entidad.

información relacionada