bash tabs heredoc

¿Cómo se escribe una pestaña en un documento aquí bash?



tabs heredoc (10)

La definición de un documento aquí está aquí: http://en.wikipedia.org/wiki/Here_document

¿Cómo se puede escribir una pestaña en un documento aquí? Como esto:

cat > prices.txt << EOF coffee/t$1.50 tea/t$1.50 burger/t$5.00 EOF

ACTUALIZAR:

Problemas tratados en esta pregunta:

  1. Expandir el carácter de tabulación
  2. Mientras no se expande el signo de dólar
  3. Incrustar un here-doc en un archivo como un script


Como han dicho otros, puede escribir CTRL-V y luego tabular para insertar una sola pestaña al escribir.

También puede desactivar la finalización de la pestaña bash temporalmente, por ejemplo, si desea pegar texto o si desea escribir aquí un documento largo con muchas pestañas:

bind ''/C-i:self-insert'' # disable tab-completion # paste some text or type your here-doc # note you don''t use "/t" you just press tab bind ''/C-i:complete'' # reenable tab-completion

EDITAR: si estás en una Mac y usas iTerm 2 , ahora hay una opción "Pegar con pestañas literales" que permite pegar código con pestañas en la línea de comando bash.


Las pestañas pegadas en un heredoc desaparecen, porque bash todavía las interpreta como caracteres especiales que marcan el inicio de una secuencia / solicitud de autocompletado.

Si desea copiar rápidamente un heredoc en el shell actual, puede hacerlo desactivando la finalización automática durante la vigencia del shell actual.

Esto es lo que sucede con la finalización automática normal si pega una pestaña que contiene heredoc:

$ cat <<EOF TABAFTERTABBEFORE TABAFTERTABBEFORE TABAFTERTABBEFORE TABAFTERTABBEFORE TABAFTERTABBEFORE EOF TABAFTERTABBEFORE TABAFTERTABBEFORE TABAFTERTABBEFORE TABAFTERTABBEFORE TABAFTERTABBEFORE

Ejecute este comando:

bind "set disable-completion on"

Pegue nuevamente y sus pestañas se conservarán:

$ cat <<EOF > TABAFTER TABBEFORE > TABAFTER TABBEFORE > TABAFTER TABBEFORE > TABAFTER TABBEFORE > TABAFTER TABBEFORE > EOF TABAFTER TABBEFORE TABAFTER TABBEFORE TABAFTER TABBEFORE TABAFTER TABBEFORE TABAFTER TABBEFORE


Noto que la respuesta correcta ya ha sido dada, pero estoy tratando de resumirla en una respuesta más sucinta.

1. No hay nada que le impida tener caracteres de pestañas literales en un documento aquí.

Para escribir una pestaña literal en el indicador Bash, debe escapar de ella. El carácter de escape es ctrl-V (a menos que tenga enlaces personalizados para anular esto).

$ echo -n ''t<ctrl-v><tab>ab'' | hexdump -C 00000000 74 09 61 62 |t.ab| 00000004

En la mayoría de los editores de cualquier programador, sería trivial insertar un carácter de tabulación literal (aunque algunos editores también querrían escaparse. En Emacs, ctrl-Q TAB inserta una pestaña literal).

Para la legibilidad, podría ser mejor utilizar algún tipo de escape en lugar de un carácter de tabulación literal. En Bash, la sintaxis de cadena $ ''...'' es conveniente para esto.

2. Para evitar la expansión variable, cite todos los signos de dólar o coloque aquí el terminador de documento entre comillas.

$ hexdump -C <<HERE > t<ctrl-v><tab>/$ab HERE 00000000 74 09 24 61 62 0a |t.$ab.| 00000006 $ hexdump -C <<''HERE'' > t<ctrl-v><tab>$ab HERE 00000000 74 09 24 61 62 0a |t.$ab.| 00000006

En este contexto, no importa si usa comillas simples o dobles.

3. No estoy seguro de entender esta sub-demanda. El propósito de un documento aquí es insertarlo en un script. El ejemplo anterior ilustra cómo pasar un documento aquí a hexdump en un script, o en la línea de comando.

Si desea utilizar el mismo documento aquí varias veces, no hay una manera directa de hacerlo directamente. La secuencia de comandos podría escribir un documento aquí en un archivo temporal, luego pasar ese archivo temporal a varios comandos y luego borrar el archivo temporal. (Tenga cuidado de usar trap para eliminar el archivo temporal también en caso de que el script se interrumpa).

También puede poner el contenido del documento aquí en una variable e interpolarlo.

# Note embedded newlines inside the single quotes, # and the use of $''.../t...'' to encode tabs data=$''coffee/t$1.50 tea/t$1.50 burger/t$5.00'' # Run Word Count on the data using a here document wc <<HERE $data HERE # Count number of tab characters using another here document with the same data grep -c $''/t'' <<HERE $data HERE

De manera equivalente, puede usar echo -E "$data" | wc; echo -E "$data" | grep -c $''/t'' echo -E "$data" | wc; echo -E "$data" | grep -c $''/t'' echo -E "$data" | wc; echo -E "$data" | grep -c $''/t'' pero usar echo no es muy elegante y podría ser menos portátil (aunque si tu objetivo es bash, todos los ecos deberían ser iguales. Si tu objetivo es Bourne shell en general, también podrías gastar un proceso para cada eco).


Para mí, escribo ctrl-V seguido de ctrl-I para insertar una pestaña en el shell bash. Esto se lleva alrededor del caparazón que intercepta la pestaña, que de otra manera tiene un significado ''especial''. Ctrl-V seguido de una pestaña debería funcionar también.

Al insertar signos de dólar en un documento aquí, debe deshabilitar la interpolación de las variables del intérprete de órdenes, o bien prefija cada una con una barra invertida para escapar (es decir, /$ ).

Usando su texto de ejemplo terminé con este contenido en prices.txt:

coffee/t.50 tea/t.50 burger/t.00

porque $1 y $5 no están configurados. La interpolación puede desactivarse citando el terminador, por ejemplo:

cat > prices.txt <<"EOF"


Puede insertar su documento aquí en su script y asignarlo a una variable sin usar un archivo separado en absoluto:

#!/bin/bash read -r -d '''' var<<"EOF" coffee/t$1.50 tea/t$1.50 burger/t$5.00 EOF

Luego printf o echo -e expandirá los caracteres /t en pestañas. Puede enviarlo a un archivo:

printf "%s/n" "$var" > prices.txt

O asigne el valor de la variable a sí mismo utilizando printf -v :

printf -v var "%s/n" "$var"

Ahora var o el archivo prices.txt contiene pestañas reales en lugar de /t .

Puede procesar su documento aquí tal como se lee en lugar de almacenarlo en una variable o escribirlo en un archivo:

while read -r item price do printf "The price of %s is %s./n" $item $price # as a sentence printf "%s/t%s/n" $item $price # as a tab-delimited line done <<- "EOF" coffee $1.50 # I''m using spaces between fields in this case tea $1.50 burger $5.00 EOF

Tenga en cuenta que usé <<- para el operador aquí doc en este caso. Esto me permite sangrar las líneas del documento aquí para la legibilidad. La sangría debe consistir solo en pestañas (sin espacios).


Re: sub pregunta # 3, leí esta pregunta como:

"¿[Qué] si quisiera [...] almacenar el aquí-doc comentado en el mismo archivo que el script para referencia posterior?"

Use el nombre del script como salida del documento aquí, agregando en lugar de reemplazar, suponiendo que el ejecutor también tenga permisos de escritura. Los comentarios de Shell no se interpretan durante un bloque de doc aquí.

_thisline=${LINENO} cat <<EOF >>$0 #====== $(date) ========= #On this run, these variable values were used as of line ${_thisline}: A=${A}, B=${B}, B=${C} EOF

De manera similar, puede usar un documento aquí para escribir un nuevo script expandiendo variables a valores, ejecutarlo, y luego tiene un registro exacto de lo que se ejecutó en lugar de tener que rastrear el código.


Si usa una herramienta como sed y cita el delimitador (EOF), las cosas pueden ser más simples:

sed ''s///t//t/g'' > prices.txt << ''EOF'' coffee/t$1.50 tea/t$1.50 burger/t$5.00 EOF

  • Citar EOF evita la expansión del parámetro (signo de dólar).
  • sed convierte ''/ t'' en caracteres de pestañas.
  • Si tiene patrones como //t en su documento aquí, entonces necesitaría una invocación de sed más compleja como: sed -e ''s///t//t/g'' -e ''s////t///t/g'' .

Una solución simple y directa al problema original es usar la expresión $ (echo $ ''...'') :

cat > prices.txt << EOF $(echo $''coffee/t$1.50'') $(echo $''tea/t$1.50'') $(echo $''burger/t$5.00'') EOF


TAB="$(printf ''/t'')" cat > prices.txt << EOF coffee${TAB}/$1.50 tea${TAB}/$1.50 burger${TAB}/$5.00 EOF