2010-09-16 12 views
21

La definición de un documento que aquí está aquí: http://en.wikipedia.org/wiki/Here_document¿Cómo se escribe una pestaña en un documento aquí bash?

Cómo se puede escribir una ficha en un documento interno? Como este:

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

ACTUALIZACIÓN:

temas tratados en esta pregunta:

  1. La ampliación de la pestaña carácter
  2. Aunque no es la expansión de la señal dólar
  3. incrustación un here-doc en un archivo como un script
+0

este sitio también es interesante: http: //tldp.org/LDP/abs/h tml/abs-guide.html # GENERATESCRIPT –

Respuesta

13

Puede integrar su aquí doc en el script y asignarlo a una variable sin utilizar 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án los caracteres \t en pestañas. Puede dar salida a un archivo:

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

o asignar el valor de la variable a sí mismo usando printf -v:

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

Ahora var o el archivo prices.txt contiene fichas reales en vez de \t.

Se podía procesar su documento como aquí se lee en lugar de almacenarla en una variable o escribir 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 he utilizado para el operador <<- doc aquí en este caso. Esto me permite sangrar las líneas del documento aquí para la legibilidad. La sangría debe consiste en solo pestañas (sin espacios).

+0

+1 Aprendí más de esta respuesta y resuelve todos mis problemas con aquí-docs y algunas maneras de usarlos de manera efectiva. –

8

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 shell, o bien prefija cada una con una barra invertida para escaparse (es decir, \$).

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

coffee\t.50 
tea\t.50 
burger\t.00 

porque $1 y $5 no están ajustadas. La interpolación se puede desconectar con una cita del terminador, por ejemplo:

cat > prices.txt <<"EOF" 
+0

+1 Gracias por su respuesta. ¿Qué pasa si quiero almacenar el documento aquí en un archivo para ejecutarlo más tarde? Por ejemplo, ¿qué pasaría si quisiera utilizar un here-doc para proporcionar un archivo de ejemplo que pueda al ejecutar un script particular y almacenar el aquí-documento comentado en el mismo archivo que el script para referencia posterior? –

+0

@D W - No estoy seguro de seguir lo que está preguntando allí - ciertamente puede insertar aquí documentos en scripts. –

+0

Gracias por mencionar la solución para incluir signos de dólar en aquí-documentos sin tener que interpretarlos. –

15
TAB="$(printf '\t')" 

cat > prices.txt << EOF 
coffee${TAB}\$1.50 
tea${TAB}\$1.50 
burger${TAB}\$5.00 
EOF 
+0

+1 Gracias por mencionar una solución fácil para incluir pestañas en here-docs. –

+5

Un atajo específico de bash sería 'TAB = $ '\ t'', abusando de las características de gettext. – Daenyth

+0

@Daenyth, gracias por la sugerencia, es una forma más elegante. –

2

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 impida que tenga caracteres de tabulación literal en un documento aquí.

Para escribir una pestaña literal en el indicador Bash, debe escaparse. 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 editor de cualquier programador, debería ser trivial para insertar una tabulación carácter literal (aunque algunos editores podrían querer escapar, también. En Emacs, Ctrl-Q TAB inserta una pestaña literal).

Para legibilidad, podría ser mejor usar 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 ponga 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 utiliza comillas simples o dobles.

3. No estoy seguro de entender esta subestación. 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 utilizar trap para eliminar el archivo temporal también en caso de que se interrumpa la secuencia de comandos.)

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 

Usted podría utilizar equivalentemente echo -E "$data" | wc; echo -E "$data" | grep -c $'\t' pero utilizando eco no es muy elegante y puede ser que sea menos portátiles (aunque si su objetivo es bash, todos los ecos deben ser los mismos. Si su objetivo es la cáscara de Bourne, en general, es posible que también gasta un proceso externo para cada eco).

1

Re: los casos de preguntas # 3, leí esta pregunta como:

"[W] ue si quería [...] almacenar el aquí-doc comentado en el mismo archivo que el script para referencia posterior? "

Utilice el nombre del script como el resultado del aquí documento, anexándolo en lugar de reemplazarlo, 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 una manera similar se puede utilizar un doc aquí para escribir un nuevo guión expansión de las variables a los valores, exec, y entonces usted tiene un registro exacto de lo que se ha ejecutado en lugar de tener que rastrear el código.

5

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

También puede desactivar fiesta para rellenar la ficha temporalmente, por ejemplo, si desea pegar el texto o si desea escribir un largo aquí-doc con una gran cantidad de fichas:

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 

EDIT: Si' En una Mac y use 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 comandos de bash.

0

Una solución simple y directa al problema original es el uso de los $ (echo $ '...') idioma:

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

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

sed 's/\\t/\t/g' > prices.txt << 'EOF' 
coffee\t$1.50 
tea\t$1.50 
burger\t$5.00 
EOF 
  • EOF Citando impide la expansión de parámetros (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'.
1

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 deshabilitando la finalización automática durante la vigencia del shell actual.

Esto es lo que sucede con auto-finalización normal si pega un heredoc fichas que contienen:

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

ejecuta este comando:

bind "set disable-completion on"

Pegar de nuevo y sus pestañas se conservó:

$ cat <<EOF 
> TABAFTER  TABBEFORE 
> TABAFTER  TABBEFORE 
> TABAFTER  TABBEFORE 
> TABAFTER  TABBEFORE 
> TABAFTER  TABBEFORE 
> EOF 
TABAFTER TABBEFORE 
TABAFTER TABBEFORE 
TABAFTER TABBEFORE 
TABAFTER TABBEFORE 
TABAFTER TABBEFORE 
Cuestiones relacionadas