string - script - Cadena multilínea con espacio adicional(sangría preservada)
if bash (7)
Funcionará si lo pones de la siguiente manera:
AA=''first line
/nsecond line
/nthird line''
echo $AA
output:
first line
second line
third line
Quiero escribir algunos textos predefinidos en un archivo con lo siguiente:
text="this is line one/n
this is line two/n
this is line three"
echo -e $text > filename
Estoy esperando algo como esto:
this is line one
this is line two
this is line three
Pero conseguí esto:
this is line one
this is line two
this is line three
Estoy seguro de que no hay espacio después de cada /n
, pero ¿cómo sale el espacio extra?
He encontrado más soluciones ya que quería tener cada línea correctamente sangrada:
Puedes usar
echo
:echo "this is line one" / "/n""this is line two" / "/n""this is line three" / > filename
No funciona si coloca
"/n"
justo antes de/
al final de una línea.Alternativamente, puedes usar
printf
para una mejor portabilidad (se me ocurrió que tuve muchos problemas con elecho
):printf ''%s/n'' / "this is line one" / "this is line two" / "this is line three" / > filename
Otra solución podría ser:
text='''' text="${text}this is line one/n" text="${text}this is line two/n" text="${text}this is line three/n" printf "%b" "$text" > filename
o
text='''' text+="this is line one/n" text+="this is line two/n" text+="this is line three/n" printf "%b" "$text" > filename
Es posible mezclar
printf
ysed
. Sin embargo, no es fácil refactorizar el código de esta manera, ya que codifica el nivel de sangrado en el código. Pongo el ejemplo en un bloque if para que haya una sangría:if something then printf ''%s'' '' this is line one this is line two this is line three '' | sed ''1d;$d;s/^ //g'' fi
Es posible usar una función auxiliar y algunos trucos de sustitución de variables:
unset text _() { text="${text}${text+ }${*}"; } # That''s an empty line which demonstrates the reasoning behind # the usage of "+" instead of ":+" in the variable substitution # above. _ "" _ "this is line one" _ "this is line two" _ "this is line three" unset -f _ printf ''%s'' "$text"
Heredoc suena más conveniente para este propósito. Se utiliza para enviar varios comandos a un programa de intérprete de comandos como ex o cat
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
La cadena después de ''<<'' indica dónde detenerse.
Para enviar estas líneas a un archivo, usa:
cat > $FILE <<- EOM
Line 1.
Line 2.
EOM
También puedes almacenar estas líneas en una variable:
read -r -d '''' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM
Esto almacena las líneas a la variable llamada VAR
.
Al imprimir, recuerde las citas alrededor de la variable, de lo contrario no verá los caracteres de nueva línea.
echo "$VAR"
Aún mejor, puedes usar la sangría para hacer que se destaque más en tu código. Esta vez solo agregue un ''-'' después de ''<<'' para evitar que aparezcan las pestañas.
read -r -d '''' VAR <<- EOM
This is line 1.
This is line 2.
Line 3.
EOM
Pero luego debe usar tabulaciones, no espacios, para la sangría en su código.
La siguiente es mi forma preferida de asignar una cadena multilínea a una variable (creo que se ve bien).
read -r -d '''' my_variable << /
_______________________________________________________________________________
String1
String2
String3
...
StringN
_______________________________________________________________________________
El número de guiones bajos es el mismo (aquí 80) en ambos casos.
Si estás tratando de convertir la cadena en una variable, otra forma fácil es algo como esto:
USAGE=$(cat <<-END
This is line one.
This is line two.
This is line three.
END
)
Si sangra su cadena con pestañas (es decir, ''/ t''), la sangría se eliminará. Si hace sangría con espacios, la sangría quedará en.
NOTA: Es significativo que el último paréntesis de cierre esté en otra línea. El texto END
debe aparecer en una línea por sí mismo.
en un script de bash los siguientes trabajos:
#!/bin/sh
text="this is line one/nthis is line two/nthis is line three"
echo $text > filename
alternativamente:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
cat nombre de archivo da:
this is line one
this is line two
this is line three
echo
agrega espacios entre los argumentos que se le pasan. $text
está sujeto a expansión variable y división de palabras, por lo que su comando echo
es equivalente a:
echo -e "this" "is" "line" "one/n" "this" "is" "line" "two/n" ...
Puede ver que se agregará un espacio antes de "this". Puede eliminar los caracteres de nueva línea y citar $text
para conservar las nuevas líneas:
text="this is line one
this is line two
this is line three"
echo "$text" > filename
O puedes usar printf
, que es más robusto y portátil que el echo
:
printf "%s/n" "this is line one" "this is line two" "this is line three" > filename
En bash
, que es compatible con la expansión de llaves, incluso podría hacer:
printf "%s/n" "this is line "{one,two,three} > filename