sed: inserindo texto antes do final da seção HEAD

4

Eu preciso inserir algum texto em um arquivo HTML antes do final da seção HEAD .

Estou tentando:

sed -i "s#</head>#<style> @page { prince-shrink-to-fit: auto }
.repository-with-sidebar.with-full-navigation .repository-content 
{width: 950px ! important;} </style>\n</head>#" ${1}"/"${2}"/"${i}.html

Estou recebendo um erro:

sed: 1: command a expects \ followed by text

Eu apenas não vejo o meu erro. Eu até tentei usar aspas simples em torno do estilo.

O texto exato que quero inserir antes do final da seção HEAD é:

<style>
@page { prince-shrink-to-fit: auto }
.repository-with-sidebar.with-full-navigation .repository-content 
{width: 950px ! important;}
</style>

Editar: aqui está o comando exato:

sed -i "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 950px ! important;} </style>\n</head>#" ${1}"/"${2}"/"${i}.html

Editar 2: Em um esforço para tentar certificar-se de que eu estava formatando o comando corretamente, estou tentando fazer isso também:

strToInsert='<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 950px ! important;} </style>'

sed -i "s#</head>#$strToInsert\n</head>#" ${1}"/"${2}"/"${i}.html

Isso me faz perceber que pode ser um problema com o texto que estou inserindo.

    
por GameDeveloper 11.04.2015 / 23:01

2 respostas

4

No local sed requer a criação de um arquivo de backup durante o processo. A opção -i no sed da Apple requer um argumento de extensão (para o arquivo de backup criado) e consome o próximo argumento. Isso significa que você está dizendo que deseja criar um arquivo de backup com a extensão " #s</head>#... ".

O erro significa que você está se referindo ao a comando ppend . Eu estou indo supor que o valor de $1 começa com um a . Porque -i do argumento anterior sed acha que este é o script a ser executado, em vez do caminho para o arquivo a ser alterado, e você obtém erros de acordo. Este é exatamente o erro que você obteria com a Apple sed e um comando a inválido:

$ sed a
sed: 1: "a": command a expects \ followed by text

Forneça um argumento de extensão para -i no seu comando sed :

sed -i.bak "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 50px ! important;} </style>\n</head>#" "${1}/${2}/${i}.html"

e as coisas funcionarão (embora note que \n não é um escape de nova linha). Se você usa aspas simples, pode até tirar o espaço de " !important ".

Os itens acima funcionarão no GNU sed , mas observe que -i não é um Opção POSIX e geralmente não é portável.

Muitas vezes é recomendado não usar a modificação no local de qualquer maneira, e lidar com o trabalho com uma cópia do arquivo explicitamente você mesmo. Isso depende de você, no entanto.

Você deve citar as expansões da variável ${1} , etc. A citação apenas das barras é inútil, porque elas são sempre literais.

    
por 11.04.2015 / 23:23
4

Minhas desculpas, mas ler sua declaração O texto exato que eu quero inserir após o término da seção HEAD é ... me levou inicialmente a acreditar que estávamos falando sobre acrescentar texto à seção de arquivo inserindo antes - então escrevi essa resposta primeiro. Depois de reler a pergunta e estudar mais de perto o seu exemplo sed command - Acho que entendo que isso realmente é sobre inserir texto antes de uma partida. Então essa resposta está agora aqui também - você encontrará instruções abaixo para fazer qualquer coisa.

Para seguramente i nsert ou a ppend uma string arbitrária na cabeça / cauda de uma linha w / sed você tem algumas opções, cada uma mais complexa que a anterior.

O primeiro - e o mais simples de todos - é o comando r ead. Requer zero de escape. Por exemplo, se a string que você deseja anexar estivesse localizada no arquivo ./append , você poderia fazer:

sed '\|</head>|r ./append' <infile >outfile

Ou para inseri-lo à frente da partida, você pode combinar um ciclo antes de ser impresso com um pequeno lookahead como:

sed -e '$!N;\|\n</head>|r ./insert' -e 'P;D' <infile >outfile

Mas r ead está escrito para stdout - e não sei como isso funcionaria com a opção -i nplace (que na maioria das vezes é apenas um hack feio na minha opinião, de qualquer maneira) . Suponho que sed deve fazer a mesma coisa que faz com p rint e redirecionar o stdout para o arquivo de edição com o nome -i nplace.

Outra opção é usar o comando a ppend - para acrescentar . Para fazer isso com segurança, você precisa apenas escapar de \n ewlines e barras invertidas. Você pode fazer isso como:

printf %s\n "$str_to_append" |
sed 's|\|&&|g;$!s|$|\|;1i\
    \|</head>|a\' |
sed -f - infile >outfile
Entretanto, o

a ppend está definido para se comportar como r ead, e, por isso, estou novamente inseguro sobre como ele pode se comportar em um hack -i n-place.

Se você substituir a\ acima com i\ , i insere o texto para stdout (ou denominado -i nplace edit-file - se isso funciona para sua implementação) antes o espaço do padrão é escrito.

Se você gosta de trabalho extra, (ou, no único uso prático que posso imaginar, você está agendando vários r eads / a ppends por linha em uma determinada ordem) ele pode ser usado para inserções da mesma forma que fiz com r antes:

printf %s\n "$str_to_append" |
sed 's|\|&&|g;$!s|$|\|;1i\
    \|\n</head>|a\' |
sed -e '$!N' -f - -e 'P;D' infile >outfile

A última oferta que vou oferecer é quase idêntica, exceto que você também deve escapar de & e delimitador (que normalmente é / ) . Poderia funcionar assim:

printf %s\n "$str_to_append" |
sed 's|[\/&]|\&|g
   $!s|$|\|;$s|$|/|
     1i\
     /<\/head>/s/^/\' |
sed -f - infile >outfile

Isso afetará uma inserção - basta trocar o ^ por um $ se você desejar anexar a string dessa maneira.

Tenho certeza de que funcionará se você adicionar a opção -i ou não.

Uma última nota, em vez de usar -i , você também pode:

sed '$d;\|</head>|r ./append' <<IN >infile
$(   cat <infile; echo .)
IN

... ou, para uma inserção:

sed -e '$d;N;\|\n</head>|r ./insert' -e 'P;D' <<IN >infile
$(   cat <infile; echo .)
IN

... que terá o seu infile editado no local sem quaisquer soluços de permissão não intencionais, pois -i pode afetar.

    
por 12.04.2015 / 00:03