【问题标题】:RegEx/SED? Replace hierarchical paths in an XML file with a single directory name正则表达式/SED?将 XML 文件中的分层路径替换为单个目录名称
【发布时间】:2014-01-10 12:48:18
【问题描述】:

我希望有人能帮我解决这个问题 - 我怀疑答案可能是 RegEx 或 Sed 命令,但我不知道该怎么做。

上下文:我想清除我的 iTunes 音乐收藏,因此我创建了一个 iTunes 播放列表并将我想保留的相应 mp3/aacs 复制到 USB 驱动器。下面是播放列表 XML 文件中与一首歌曲相关的片段:

<key>Persistent ID</key><string>B123AA625019E726</string>
<key>Track Type</key><string>File</string>
<key>Purchased</key><true/>
<key>Location</key><string>file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music/Adele/21/01%20Rolling%20In%20The%20Deep.m4a</string>
<key>File Folder Count</key><integer>5</integer>
<key>Library Folder Count</key><integer>1</integer>

然后我在删除整个库后安装了 Mavericks (Mac),并打算将我导出的内容重新导入。问题是音乐文件复制到单个文件夹和播放列表引用原始分层位置。我想将播放列表中每首歌曲的“位置”值更改为新的单个目录,以便我可以导入播放列表并保留每首歌曲的元数据。我发现/替换将不起作用,因为原始位置是 2/3/4 等深。如果有帮助,我可以进入 Mac 或 Linux 提示符。有人可以帮我解决这个问题吗?

如果您能提供帮助,请提前(非常感谢)!

【问题讨论】:

  • 你是说现在所有歌曲都在一个文件夹中,所以该位置中最后一个 / 之前的任何内容都需要替换?
  • 问题中的示例不是有效的 XML:&lt;key&gt;Location&lt;/key&lt;string&gt;。错字或损坏的文件?
  • 嗨 Harald,是的,这完全正确 - 所有音乐文件现在都在一个文件夹中 :( 上述 XML 文件中显示的原始文件夹位置是 'n' 级深 - (有些是艺术家,专辑 - 其他人通过编辑等)。我希望用我现在留下的单个文件夹的路径替换这些“n”级别,以便我可以重新导入这个播放列表(包括元数据)。
  • 嗨 Louis,你是对的 - 它不是有效的 XML!这不是错字,而是 iTunes 存储数据的方式!
  • 你应该更准确地解释一下,什么是输入,什么是期望的输出。举个例子。

标签: xml regex file sed itunes


【解决方案1】:

以下示例使用 sed 将字符串“file://localhost/Users/bc”替换为“file:///home/bc”

示例

$ sed -e 's/file:\/\/localhost\/Users\/bc/file:\/\/\/home\/bc/g' data.xml
<song>
  <key>Persistent ID</key>
  <string>B123AA625019E726</string>
  <key>Track Type</key>
  <string>File</string>
  <key>Purchased</key>
  <true/>
  <key>Location</key>
  <string>file:///home/bc/Music/iTunes/iTunes%20Media/Music/Adele/21/01%20Rolling%20In%20The%20Deep.m4a</string>
  <key>File Folder Count</key>
  <integer>5</integer>
  <key>Library Folder Count</key>
  <integer>1</integer>
</song>

data.xml

<song>
  <key>Persistent ID</key>
  <string>B123AA625019E726</string>
  <key>Track Type</key>
  <string>File</string>
  <key>Purchased</key>
  <true/>
  <key>Location</key>
  <string>file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music/Adele/21/01%20Rolling%20In%20The%20Deep.m4a</string>
  <key>File Folder Count</key>
  <integer>5</integer>
  <key>Library Folder Count</key>
  <integer>1</integer>
</song>

【讨论】:

  • 嗨,马克,与音乐文件相关的每个字符串 'file://localhost/Users/bc' 都会在任意数量的子目录下包含音乐文件。我希望用一个目录替换任意数量的目录 - 我想你需要一个正则表达式 - 你能确认 - 你知道它会是什么吗?!?谢谢!
【解决方案2】:

我假设您的音乐文件都在 file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music/Adele/ 的子文件夹下,您想将它们直接更改为 file://localhost /Users/bc/Music/iTunes/iTunes%20Media/Music/Adele/

sed '/<key>Location<\/key</s!file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music
/Adele/.*/\([^/]\+\)</string>!file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music
/Adele/\1</string>!' data.xml

/&lt;Key&gt;Location&lt;\/key&lt; 匹配你需要更改的行,然后替换,删除 Adele 之后的所有子文件夹,保留文件名 \1 并将其附加到路径 Adele/

我的脚本只是将新内容输出到控制台,您可以将其重定向到新的 xml 文件,如

sed '/<key>Location<\/key</s!file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music
/Adele/.*/\([^/]\+\)</string>!file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music
/Adele/\1</string>!' data.xml > data_new.xml

感谢弗朗西斯科指出我的编辑错误

【讨论】:

  • 你好QAMichaelPeng!你的假设是完全正确的。我尝试了您的 sed 命令,但它没有更改文件中的任何内容。这是位置节点的另一个示例:Locationfile://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music/Kavinsky/Nightcall%20-%20Single/01 %20Nightcall.m4a
  • @QAMichaelPeng 的回复无效编辑:我的脚本只是将新内容输出到控制台,您可以将其重定向到新的 xml 文件,如 sed /Location&lt;/key!file://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music/Adele/\1!data.xml > data_new .xml
  • 非常感谢弗朗西斯科和 QAMichaelPeng。我尝试了您的建议,输出的文件与输入文件相同。如果有帮助,这里是 Location 节点的另一个示例:Locationfile://localhost/Users/bc/Music/iTunes/iTunes%20Media/Music/Syd%20Matters/Brotherocean/02 %20Hi%20Life.m4a 顺便说一下,在上面的示例中,我希望所有音乐文件都出现在 Music 文件夹下(不是 Music/Adele/),所以我假设我只是删除了 Adele。再次感谢 - 新年快乐!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-23
  • 2012-01-26
  • 1970-01-01
  • 2018-08-22
  • 2010-11-23
相关资源
最近更新 更多