연결된 XML 파일 정리

연결된 XML 파일 정리

난 내 문제를 고치려고 노력 중이야맛있는 내보내기 스크립트새로운 "장난"한 번에 1000개의 북마크만 제공됩니다. 스크립트는 여러 호출의 결과(XML)를 하나의 파일로 연결하므로 이제 결과 파일에서 머리글과 바닥글 텍스트를 제거해야 합니다. 예:

<?xml ...
<posts ...
  <post ...
  ...          # 998 other posts
  <post ...
</posts>     # Line 1003
# The above lines are repeated N times before the final line:
</posts>

즉, <post(배타적으로) 세 번째 줄과 마지막 줄 사이에서 시작하지 않는 줄을 삭제하고 싶고, 각 XML 블록에는 마지막 줄을 제외하고 정확히 1003줄이 있습니다.

나는 완벽하다고 생각하거나 sed완벽 awk해야합니다.

답변1

데이터 형식이 일관적이므로 헤더와 트레일러가 친구가 됩니다. 이것은 마지막 짧은 파일에도 작동합니다.

cat file | tail -n +3 | head -n -1 > trimmed_file

tail -n +3은 파일의 세 번째 줄부터 끝까지 모든 것을 가져오는 반면, head -n -1은 파일의 마지막 줄을 제외한 모든 것을 가져옵니다.

잘린 파일 세트가 있으면 전체 파일의 적절한 머리글 및 바닥글 섹션과 함께 배치하십시오.

업데이트: 여러 개의 추가 파일을 생성하지 않으려면 해당 파일을 for 루프로 감싸세요.

for i in *
do
    cat $i | tail -n +3 | head -n -1 >> newfile
done

head를 통해 파일 중 하나를 실행하여 처음 3줄을 추출한 다음 위의 for 루프를 실행하여 헤더 템플릿을 가져옵니다. 그런 다음 tail을 사용하여 비슷한 작업을 수행하여 파일 중 하나의 마지막 줄을 가져와 새 파일에 추가합니다. 머리글과 바닥글 정보를 업데이트해야 할 것 같습니다.

답변2

작동하게 만들다:

sed -i -e '3,${/^</d}' file

즉, 3번째 줄과 마지막 줄 사이에서 로 시작하는 줄을 모두 삭제합니다 <. 죄송합니다. 원래 게시물에는 들여쓰기가 표시되지 않았습니다.

답변3

이건 좀 어색해 보이는데요. 왜 들어오는 데이터를 직접 처리하지 않는 걸까요?

bookmarks_count=$chunk_size
total_bookmarks_count=0
{
  while [ $bookmarks_count -eq $chunk_size ]; do
    chunk=$(wget … -O - "$EXPORT_URL?start=$total_bookmarks_count")
    bookmarks_count=$(printf %s "$chunk" | grep -c "$bookmark_prefix")
    total_bookmarks_count=$((total_bookmarks_count + bookmarks_count))
    printf %s "$chunk" |
    sed -e 's#><#>\n<#g' -e "$EXPORT_COMPATIBILITY" -e "$EXPORT_COMPATIBILITY"
  done
  echo '<\/posts>'
} >"$EXPORT_PATH"

약간 까다롭기는 하지만 각 블록을 메모리에 저장하는 것을 피할 수도 있습니다. 이는 다른 쉘에서는 ksh 및 zsh에서만 작동하는 방법이며, 파이프의 오른쪽은 서브 쉘에서 실행되므로 값이 total_bookmarks_count업데이트되지 않습니다.

{
  total_bookmarks_count=0
  while
      wget … -O - "$EXPORT_URL?start=$bookmarks_count" |
      sed -e … |
      tee /dev/fd/3 |
      this_chunk_size=$(grep -c "$bookmark_prefix")
      [[ $this_chunk_size = $chunk_size ]]
  do
    ((total_bookmarks_count += chunk_size))
  done
  echo '<\/posts>' >&3
} 3>"$EXPORT_PATH"

파이프에서 얻을 수 있는 유일한 정보는 반환 상태뿐인 다른 셸에서 이 작업을 수행하는 방법은 다음과 같습니다.

: >"$EXPORT_PATH"
total_bookmarks_count=0
while
    wget … -O - "$EXPORT_URL?start=$bookmarks_count" |
    sed -e … |
    tee -a "$EXPORT_PATH" |
    [ $(grep -c "$bookmark_prefix") = $chunk_size ]
do
  total_bookmarks_count=$((total_bookmarks_count + chunk_size))
done
echo '<\/posts>' >> "$EXPORT_PATH"

관련 정보