Ubuntu 14.04 值得信赖的塔尔。
假设我有一个名为“testmag”的目录,它可能包含数百个 xml 文件,而目录又包含许多 xml 文件。我不知道任何 xml 文件的名称,但我知道其中之一包含 tag <dbname>....</dbname>
。
现在如何找到包含上述标签的文件并将标签的值作为终端中的输出
答案1
这是一个解决方案,find
它还将输出包含匹配项的文件的文件名:
find . -name "*.xml" -exec grep '<dbname>' {} \; \
-exec echo -e {}"\n" \; \
| sed 's/<dbname>\(.*\)<\/dbname>/\1/g'
解释
find . -name "*.xml"
从当前目录递归查找所有 xml 文件-exec grep '<dbname>' {} \;
在每个文件上搜索模式<dbname>
-exec echo -e {}"\n" \;
echo 文件名 + 新行(-e
选项使 echo 解释\n
)| sed 's/<dbname>\(.*\)<\/dbname>/\1/g'
通过管道输出来sed
仅打印标签之间包含的字段<dbname></dbname>
。
注意1:您可以格式化输出,echo -e ...
以便清楚地列出每个文件的结果,例如通过添加新行或下划线行,无论什么都适合您的需要。
.
注意2:每个文件的路径将相对于(例如)给出./subfolder1/file.xml
。如果您想要绝对路径,请选择find $PWD -name ...
.
答案2
使用适当的 XML 解析器来解析 XML:
shopt -s globstar nullglob
for file in **/*.xml; do
dbname=$(xmlstarlet sel -t -v '//dbname' "$file")
[[ -n "$dbname" ]] && printf "%s\t%s\n" "$file" "$dbname"
done
答案3
find
与以下一起使用xq
:
find testmag -type f -name '*.xml' -exec xq -r '..|(.dbname? // empty)' {} +
*.xml
这将找到目录中或目录下名称匹配的所有常规文件testmag
。对于这些批次,将调用以提取在这些文档中找到的xq
每个节点的值。dbname
xq
是一个类似 XML 解析器,随fromjq
一起分发yq
https://kislyuk.github.io/yq/
您是否需要具有此节点的所有 XML 文件的文件名,您可以使用
find testmag -type f -name '*.xml' -exec xq -e '..|(.dbname? // empty)' {} \; -print
...虽然这比仅仅提取节点的值要慢一些,因为我们需要xq
为每个文件调用一次。
答案4
假设我们有XMLS
包含这些文件的目录:
cat XMLS/file1
foo bar <dbname>target</dbname> baz
foo foo
cat XMLS/file2
<name>notarget</name>
我会使用这个命令:
grep -r '<dbname>' XMLS/ | sed 's/.*<dbname>\(.*\)<\/dbname>.*/\1/'
target
正如您所看到的,它返回标签内的值<dbname>
。而不是标签内的值<name>
。
递归搜索-r
的标志 。grep
sed
删除字符串中除 value 之外的所有内容target
。