Extraindo mensagem de ajuda do próprio script

3

Eu quero que minha mensagem de ajuda seja extraída do próprio script.

#!/bin/bash
#
# foo - do things
# Author: John Doe <jhon@doe>
# ----------------------------------------------
# SYNOPSIS
#   foo [OPTIONS] FILE
# 
# DESCRIPTION
#   At vero eos et accusamus et iusto odio
#   dignissimos ducimus qui blanditiis praesenti
#   voluptatum deleniti atque corrupti quos.
# ----------------------------------------------

sed -n '/# -\+$/,/# -\+$/ p' $0

Funciona! Ele imprime apenas o que está entre os dois delimitadores # -\+$ , inclusive. O problema é que não quero imprimir os delimitadores.

E você tem sugestões para um gerador de páginas man com sintaxe humana amigável?

Atualização: Talvez tenha declarado mal meu problema. Quero imprimir apenas o que está entre as duas linhas, começando com # ----- e terminando com ---- .

Eu conheço esta solução:

sed -n '/# -\+$/,/# -\+$/ p' $0 | head -n -1 | tail -n +2

Mas eu quero uma solução limpa e elegante que não pareça hackeada.

    
por Pedro Lacerda 30.09.2012 / 02:25

6 respostas

2

Tente isso, por favor:

#!/bin/bash
#
# foo - do things
# Author: John Doe <jhon@doe>
# ----------------------------------------------
# SYNOPSIS
#   foo [OPTIONS] FILE
# 
# DESCRIPTION
#   At vero eos et accusamus et iusto odio
#   dignissimos ducimus qui blanditiis praesenti
#   voluptatum deleniti atque corrupti quos.
# ----------------------------------------------


cat 'which $0' | sed -n '0,/# -\+$/d;/# -\+$/,$d;p'
    
por 30.09.2012 / 03:23
2

Você também pode realizar isso com awk :

awk '/^# --/{ flag=!flag; next}; flag' file

Dado que o texto que você está usando para delimitar o texto desejado é o mesmo no início e no final, ou seja, # -- , o normal falhará, portanto, é necessário usar um sinalizador. A próxima instrução força o awk a passar para o próximo registro, antes de imprimir o intervalo.

    
por 30.09.2012 / 03:38
2

Você pode fazer isso simplesmente com awk :

awk -v RS='\n# -+' 'NR==2' $0

RS define o separador de registro apropriadamente e NR==2 imprime o segundo registro.

Você pode remover o sinal de comentário e o espaço extra com gsub , por exemplo:

awk -v RS='\n# -+' 'NR==2 { gsub("\n# ", "\n"); print }' $0

Atualizar

Para evitar uma primeira linha vazia, adicione \n a RS , mas agora a primeira linha não é substituída por gsub , então gensub é chamado:

awk -v RS='\n# -+\n' 'NR==2 { print gensub("(^|\n)# ", "\1", "g") }' $0
    
por 30.09.2012 / 09:01
1

O que você precisa é chamado de "documento aqui". Felizmente, já está implementado no bash. Confira o seguinte URL link l

Você simplesmente usa o seguinte:

cat <<end-of-message
----------------------------
message lines...
----------------------------
end-of-message

Você pode adicionar uma condicional na parte superior do seu script para imprimir isso somente se um parâmetro for inserido ou algo assim ... como uma opção -h ou se não houver argumentos presentes.

    
por 30.09.2012 / 05:13
1

Em vez de colocar sua mensagem nos comentários no início do arquivo, você também pode emular a seção __DATA__ do Perl e algumas outras linguagens de programação antes de o script chegar:

#!/bin/sh

data=$(sed '0,/^__DATA__$/d' "$0")
printf '%s\n' "$data"

exit

__DATA__
FOO BAR BAZ
LLAMA DUCK COW

Mesma idéia geral das outras soluções baseadas em sed.

    
por 30.09.2012 / 17:24
0

Isso pode funcionar para você (GNU sed):

 sed '/^# -\+$/,//!d;//d' $0

Explicação:

  • /^# -\+$/,//!d exclui tudo não entre delimitadores
  • //d exclua os delimitadores e deixe o restante passar por

N.B. // reutiliza o regexp mais recente.

    
por 04.10.2012 / 16:24