Para isso, é melhor usar awk
para suportar operações aritméticas
cat $1 | awk -v d=$2 '/BookmarkPageNumber:/{$2-=d}1'
Eu extraí os metadados de um PDF em um arquivo .txt
usando pdftk
e agora estou tentando diminuir o valor de BookmarkPageNumber
de cada indicador por um número inteiro. O .txt
tem estas linhas:
BookmarkBegin
BookmarkTitle: Preface
BookmarkLevel: 1
BookmarkPageNumber: 10
BookmarkBegin
BookmarkTitle: Author
... and so on
Estou tentando fazer isso usando o comando substituto do sed e aqui está o que eu tenho até agora:
// $1 is the source .txt file; $2 is the decrement
// __ is a placeholder for the variable with the original value
cat $1 | sed "s/BookmarkPageNumber: [0-9]*/BookmarkPageNumber: 'expr __ - $2'/" | cat > metadata.txt
Como posso colocar o valor original em uma variável e, em seguida, substituir o palceholder __
por ele, nessa mesma expressão sed?
awk '!/BookmarkPageNumber:/ {print}; /BookmarkPageNumber:/ {print $1 " " $2-1}' old.txt > new.txt
Outra opção seria usar o próprio shell (usando 5 como exemplo, altere-o para qualquer que seja o inteiro real que você deseja subtrair):
while read key val; do
[[ $key == "BookmarkPageNumber:" ]] && let val=val-5;
echo $key $val;
done < file
Você também pode usar uma ferramenta como perl
:
perl -pe 's/(BookmarkPageNumber:\s*)(\d+)$/$1 . ($2-5)/e; ' file
E aqui está outra abordagem de awk
:
awk '$1~/BookmarkPageNumber:/{$2=$2-5}1;' file
NOTA: Eu acabei de perceber que ele queria diminuir o BookmarkPageNumber por um inteiro arbitrário, que eu inicialmente inspecionei, e a minha solução abaixo só funciona para diminuí-lo em 1. No entanto, eu me sinto pressionado a remover inteiramente considerando o esforço que eu coloquei para ele:
-------- apenas solução parcial ---------
Caso você esteja determinado a usar apenas o sed, eu tenho este 1 liner para você:
sed -r '/^BookmarkPageNumber: /{s/([0-9]*)$/@/;:loop {s/0@/@9/;/0@/b loop;};s/1@/_0/;s/2@/_1/;s/3@/_2/;s/4@/_3/;s/5@/_4/;s/6@/_5/;s/7@/_6/;s/8@/_7/;s/9@/_8/;s/ @9+$/ UNDERFLOW/;s/ _0*/ /;s/_//}' $1 >metadata.txt
Nota: isso só funciona para números decimais naturais, espero que esteja tudo bem para você.
Ah, ainda tem detecção de underflow. Então, caso você queira que seus números de página sejam saturados em 0, basta substituir UNDERFLOW
por 0
E eu concordo com qualquer um que chama isso de mera manobra intelectual, porque é isso que é.
p.s .: você provavelmente deve verificar se os descritores de arquivos de entrada e saída não apontam para o mesmo arquivo, senão o arquivo será truncado se o usuário tiver acesso de gravação.
Tags sed regular-expression