[resolvido] comando sed

Iniciado por sigur, 30 de Maio de 2012, 16:37

tópico anterior - próximo tópico

sigur

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
sed /\usepackage/%\usepackage/ 1.tex > 2.tex mas o erro foi 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.

irtigor

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.

sigur

Citação de: irtigor online 30 de Maio de 2012, 17:08
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
sed 's;^\\usepackage;%\\usepackage;' 's;^\\title;%\\title;' 1.tex mas não deu.

Tentei 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.

irtigor

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.

sigur

Citação de: irtigor online 30 de Maio de 2012, 22:11
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:
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.


sigur

Citação de: irtigor online 31 de Maio de 2012, 08:39
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.

sigur

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.

irtigor

A contra barra é um carácter de escape. Use
grep -E '(^\\title|^\\author)' arquivo.tex

sigur

Citação de: irtigor online 31 de Maio de 2012, 23:59
A contra barra é um carácter de escape. Use
grep -E '(^\\title|^\\author)' arquivo.tex

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

for file in texfiles/*.tex; do
sed -e 's;\\maketitle;\\maketitle\\thispagestyle{empty}\\pagestyle{empty};'  -i $file
done


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



sigur

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
if [ -f *.aux ];
then
rm *.aux
rm *.log
else
echo "nao tem nenhum aux"
fi

mas aparece o erro
./lista.sh: linha 9: [: número excessivo de argumentos


Alguma ajuda?

irtigor

"-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.

sigur

Citação de: irtigor 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.

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
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.

irtigor


for i in *.aux; do
   [[ -f "$i" ]] || continue
   rm "$i"
done



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.

sigur

Opa, legal hein. Valeu pela ajuda.

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

Mas está ficando show de bola.
Obrigado.