Autor Tópico: [resolvido] comando sed  (Lida 12024 vezes)

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
[resolvido] comando sed
« Online: 30 de Maio de 2012, 16:37 »
Pessoal, tentei adaptar um modelo de uso do sed, que encontrei aqui, para comentar uma linha de um arquivo, mas não estou conseguindo.

Pois bem, quero comentar todas as linhas do meu arquivo TeX que começam com \usepackage.

O problema é que não consigo fazer a troca, ou melhor, inserir o símbolo % na frente destas linhas, pois eu acho que a barra e o % precisar ser passados de modo diferente.

Tentei
Código: [Selecionar]
sed /\usepackage/%\usepackage/ 1.tex > 2.tex mas o erro foi
Código: [Selecionar]
sed: -e expressão #1, caractere 12: comando desconhecido: `%'
alguma ajuda?
Em resumo, preciso inserir % em vários arquivos TeX nas linhas que começam com \usepackage

Obrigado.
« Última modificação: 16 de Junho de 2012, 12:49 por sigur »

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: comando sed
« Resposta #1 Online: 30 de Maio de 2012, 17:08 »
Código: [Selecionar]
sed 's;^\\usepackage;%\\usepackage;' 1.tex
Substitui linhas que começam com \usepackage por %\usepackage. Você pode usar a opção "-i/--in-place" pra substituir diretamente.

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #2 Online: 30 de Maio de 2012, 21:20 »
Código: [Selecionar]
sed 's;^\\usepackage;%\\usepackage;' 1.tex
Substitui linhas que começam com \usepackage por %\usepackage. Você pode usar a opção "-i/--in-place" pra substituir diretamente.

perfeito!!

muito obrigado. O que quer dizer com 'substituir diretamente'?

Só mais uma pergunta: se eu quiser fazer mais de uma substituição no mesmo arquivo, por exemplo, comentar também as linhas que começam com \title, posso fazer como? tentei fazer
Código: [Selecionar]
sed 's;^\\usepackage;%\\usepackage;' 's;^\\title;%\\title;' 1.tex mas não deu.

Tentei
Código: [Selecionar]
sed 's;^\\usepackage;%\\usepackage;'  1.tex | sed 's;^\\title;%\\title;' > 2.tex mas não deu

Será que terei que criar um .sh e inserir um monte de linhas, uma para cada comando sed trocando as coisas?

Obrigado mais uma vez. Já ajudou bem.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: comando sed
« Resposta #3 Online: 30 de Maio de 2012, 22:11 »
Código: [Selecionar]
sed -e 's;^\\usepackage;%\\usepackage;' -e 's;^\\title;%\\title;' 1.tex
Com um "-i" o arquivo 1.tex seria modificado, no lugar do resultado aparecer na saída padrão.

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #4 Online: 30 de Maio de 2012, 22:21 »
Código: [Selecionar]
sed -e 's;^\\usepackage;%\\usepackage;' -e 's;^\\title;%\\title;' 1.tex
Com um "-i" o arquivo 1.tex seria modificado, no lugar do resultado aparecer na saída padrão.

ah, entendi. então ele altera e escreve no próprio arquivo? é como se fosse mexer em 1.tex e mandar a saída pro próprio 1.tex?

eu havia tentado colocar 1.tex > 1.tex no fim do comando, mas o resultado ficou um arquivo em branco.
daí eu fiz uma gambiarra. Veja o que eu fiz:
Código: [Selecionar]
cat texfiles/comm*.tex > tudo.tex
sed 's;^\\documentclass;%\\documentclass;' tudo.tex > temp.tex
mv temp.tex tudo.tex
sed 's;^\\usepackage;%\\usepackage;' tudo.tex > temp.tex
mv temp.tex tudo.tex
sed 's;^\\begin{document};%\\begin{document};' tudo.tex > temp.tex
mv temp.tex tudo.tex
sed 's;^\\end{document};%\\end{document};' tudo.tex > temp.tex
mv temp.tex comm.tex
rm tudo.tex

Deu certo, mas não ficou nem um pouco legal.

Agora vou tentar sua dia.
Mais uma vez, obrigado.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #6 Online: 31 de Maio de 2012, 09:49 »
http://wiki.bash-hackers.org/howto/redirection_tutorial#why_sed_sfoobarfile_file_doesn_t_work

muito bom. consegui usar suas dicas e colocar um monte de subs. no mesmo comando. agora é só executar o .sh e partir pro abraço.

Valeu hein.

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #7 Online: 31 de Maio de 2012, 21:08 »
Opa, eu novamente.

Não estou tendo tanto sucesso pra compilar tudo de uma vez. Mas isso é detalhe. Portanto, estou querendo fazer o seguinte:

para cada arquivo .tex dentro de uma pasta, queria copiar as linhas que começam com \title e com \author, copia-las nesta ordem, para um outro arquivo.

Tentei usar o cat 1.tex | grep \title  mas o problema é que ele retorna também as linhas que começam com \maketitle. Não sei porque, mas ele não segue fielmente a palavra.

A outra dificuldade é fazer buscar, para um mesmo arquivo, as duas linhas de uma vez.

Será que dá pra fazer um .sh?
Valeu.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: comando sed
« Resposta #8 Online: 31 de Maio de 2012, 23:59 »
A contra barra é um carácter de escape. Use
Código: [Selecionar]
grep -E '(^\\title|^\\author)' arquivo.tex

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #9 Online: 01 de Junho de 2012, 12:58 »
A contra barra é um carácter de escape. Use
Código: [Selecionar]
grep -E '(^\\title|^\\author)' arquivo.tex

opa, legal. Obrigado.
Veja como está ficando:

Código: [Selecionar]
for file in texfiles/*.tex; do
sed -e 's;\\maketitle;\\maketitle\\thispagestyle{empty}\\pagestyle{empty};'  -i $file
done

Código: [Selecionar]
rm indice-comm.tex # dá erro se o file não existe. queria colocar um if
for file in texfiles/comm*.tex ; do
grep -E '^.title|^.author' $file >> indice-comm.tex # trocar pela sua sugestão
echo -e " " >>  indice-comm.tex # gambiarra pra pular linha no arquivo
sed -e 's;^\\title;\\titulo;' -e 's;^\\author;\\autor;' -i indice-comm.tex
done

# compilar em pdf os comm*.tex da pasta texfiles
for file in texfiles/comm*.tex; do
pdflatex $file
pdflatex $file
mv comm*.pdf pdffiles/
done

rm *.aux
rm *.log
#rm *.out

# juntar todos os comm*.pdf em um arquivo só
# chamado resumos-comm.pdf
pdftk pdffiles/comm*.pdf cat output resumos-comm.pdf


Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #10 Online: 07 de Junho de 2012, 22:23 »
Pessoal, queria fazer um teste para saber se existe algum arquivo no diretório com extensão .log ou .aux. Caso sim, queria redeltar todos eles.

Tentei fazer
Código: [Selecionar]
if [ -f *.aux ];
then
rm *.aux
rm *.log
else
echo "nao tem nenhum aux"
fi
mas aparece o erro
Código: [Selecionar]
./lista.sh: linha 9: [: número excessivo de argumentos

Alguma ajuda?

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: comando sed
« Resposta #11 Online: 07 de Junho de 2012, 23:18 »
"-f" testa se 1 arquivo é normal. Se no diretório tem 1.aux e 2.aux, *.aux vai ser expandido para esses dois, então vai ficar [ -f 1.aux 2.aux ] o que é errado.

Você pode usar um loop ou remover de qualquer forma, redirecionando o stderr pra /dev/null.

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #12 Online: 08 de Junho de 2012, 09:31 »
"-f" testa se 1 arquivo é normal. Se no diretório tem 1.aux e 2.aux, *.aux vai ser expandido para esses dois, então vai ficar [ -f 1.aux 2.aux ] o que é errado.

Você pode usar um loop ou remover de qualquer forma, redirecionando o stderr pra /dev/null.

Hum, entendi o uso do -f.

Quando você diz para usar um loop, seria um for? Mas como saber se existem arquivos .aux na pasta, para que o rm dentro do for não dê erro?

Veja se entendi: essa parte do null seria para mandar a msg de erro pra lá? Lembro de ter lido algo assim. Então, se eu fizer apenas
Código: [Selecionar]
rm *.aux > /dev/null sempre dará certo, pois não verei msg de erros na tela? Se tiver erros, isso deixará mais lento a execução?

Valeu por enquanto.

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: comando sed
« Resposta #13 Online: 08 de Junho de 2012, 10:41 »
Código: [Selecionar]
for i in *.aux; do
   [[ -f "$i" ]] || continue
   rm "$i"
done

Código: [Selecionar]
rm *.aux 2> /dev/null
[[ $? -eq 1 ]] && echo "nao tem nenhum aux"

O segundo deve ser mais rápido porque pega todos os arquivos de uma só vez, enquanto o outro trabalha em série.

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: comando sed
« Resposta #14 Online: 08 de Junho de 2012, 10:55 »
Opa, legal hein. Valeu pela ajuda.

Só não entendi muito o porque de dois [[.

Mas está ficando show de bola.
Obrigado.