.txt
를 사용하여 파일에 있는 PDF의 메타데이터를 추출한 후 이제 각 북마크의 값을 정수만큼 줄이려고 pdftk
합니다 . 다음 줄이 BookmarkPageNumber
있습니다 .txt
.
BookmarkBegin
BookmarkTitle: Preface
BookmarkLevel: 1
BookmarkPageNumber: 10
BookmarkBegin
BookmarkTitle: Author
... and so on
이 작업을 수행하기 위해 sed에 대한 대체 명령을 사용하려고 합니다. 이것이 지금까지 제가 가지고 있는 것입니다.
// $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
__
원래 값을 변수에 넣은 다음 동일한 sed 표현식에서 자리 표시자를 어떻게 바꿀 수 있습니까 ?
답변1
이를 위해서는 awk
산술 연산을 지원하므로 사용하는 것이 좋습니다.
cat $1 | awk -v d=$2 '/BookmarkPageNumber:/{$2-=d}1'
답변2
awk '!/BookmarkPageNumber:/ {print}; /BookmarkPageNumber:/ {print $1 " " $2-1}' old.txt > new.txt
답변3
또 다른 옵션은 쉘 자체를 사용하는 것입니다(예를 들어 5를 빼려는 실제 정수로 변경).
while read key val; do
[[ $key == "BookmarkPageNumber:" ]] && let val=val-5;
echo $key $val;
done < file
또는 다음과 같은 도구를 사용할 수 있습니다 perl
.
perl -pe 's/(BookmarkPageNumber:\s*)(\d+)$/$1 . ($2-5)/e; ' file
또 다른 접근 방식은 다음과 같습니다 awk
.
awk '$1~/BookmarkPageNumber:/{$2=$2-5}1;' file
답변4
참고: 나는 그가 원래 읽은 임의의 정수로 BookmarkPageNumber를 줄이고 싶어한다는 것을 깨달았습니다. 반면 아래 솔루션은 1만 줄였습니다. 그러나 노력한 결과 완전히 제거하기는 어렵습니다.
--------해결책의 일부만---------
sed만 사용하고 싶다면 다음 한 줄을 참조하세요.
sed -r '/^BookmarkPageNumber: /{s/([0-9]*)$/\1@/;: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
참고: 이것은 자연 십진수에만 작동합니다. 이것이 괜찮기를 바랍니다.
아, 심지어 언더플로우 감지 기능도 있습니다. 따라서 페이지 번호를 0으로 포화시키려면 다음 UNDERFLOW
으로 바꾸십시오.0
나는 이것이 단지 지적 망상일 뿐이라고 말하는 사람의 의견에 동의합니다. 왜냐하면 그것이 바로 그것이기 때문입니다.
ps: 입력 및 출력 파일 설명자가 동일한 파일을 가리키는지 확인해야 합니다. 그렇지 않으면 사용자에게 쓰기 권한이 있는 경우 파일이 잘립니다.