清理串联的 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 执行类似的操作以获取其中一个文件的最后一行并将其附加到 newfile 中。我想您需要更新页眉和页脚信息。

答案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 的方法;在其他 shell 中,管道的右侧在子 shell 中运行,因此 的值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"

这是一种使此方法在其他 shell 中工作的方法,其中您可以从管道中获取的唯一信息是其返回状态。

: >"$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"

相关内容