
Necesito ayuda para resolver este problema, tengo un archivo que contiene una lista de nombres:
nombres.txt
roger
peter
henry
Me gustaría concatenar :
después de cada nombre.
for i in $(cat names.txt); do
$i+=$i":"
done
El resultado que quiero es esteroger:peter:henry
pero estoy obteniendo este resultadoroger:peter:henry:
Respuesta1
Existe una herramienta que puede hacerlo por ti:paste
$ paste -sd: names.txt
roger:peter:henry
Respuesta2
Una solución alternativa con sed
y tr
:
sed '$!s/$/:/' names.txt | tr -d '\n'
Salidas:
roger:peter:henry
Respuesta3
paste
es la herramienta adecuada para el trabajo. Pero solo para completar, aquí le mostramos cómo hacer lo que estaba intentando:
k="$(head -n1 names.txt)";
for i in $(tail -n+2 names.txt); do
k="$k:$i";
done
Esto produce:
$ echo "$k"
roger:peter:henry
Respuesta4
$i+=$i":"
Esto no hace lo que quieres que haga. En cambio, se expande $i
en los lugares marcados e intenta ejecutar el resultado como un comando. Una asignación de shell no toma el signo de dólar en el lado izquierdo (piense en ello como si tomara el valor de la variable, aquí no queremos eso, sino la ubicación donde almacenar). Debería serlo i+=$i":"
en su lugar. O preferiblemente i+="$i:"
simplemente para acostumbrarse a citar expansiones de variables de shell.
Además, está intentando agregar a la variable utilizada como variable de bucle. Esto no es muy útil, ya que se sobrescribe en la siguiente ronda del ciclo. Además, agregará dos puntos después de cada elemento, incluido el último, por lo que tendrá uno al final. Pero podemos eliminarlo después con la ${var%suffix}
expansión.
Entonces:
s=
for i in $(cat names.txt); do
s+="$i:"
done
s=${s%:}
Aunque tenga en cuenta que la expansión sin comillas de $(cat)
procesará cualquier patrón comodín de nombre de archivo (globs), por lo que una línea *
en el archivo se expandirá a todos los archivos en el directorio actual, etc.