情况:在 Linux 中,我有一个父文件夹,里面有近 100 个不同名称的文件夹。每个文件夹都有一个文件ResourceParent.xml
和数百个不同的版本号,每个版本号都有自己的文件。我对第一级文件夹和最新版本文件夹(最高编号)中的 ResourceVer.xmlResourceVer.xml
都感兴趣,例如。ResourceParent.xml
ver548
我需要在每个文件内搜索 3 个标签.txt|.csv|.xls
,并将这些标签内的信息返回到 report.txt 文件中。标签通常在同一行,所以我认为 Grep 没问题。
我尝试过的:
grep -nr -E ".txt|.csv|.xls" . > /dir/to/the/ReportFile.txt
这会花费太长时间,因为它会搜索数千个目录中的每一个,并产生大量不必要的重复数据。
此外,我尝试根据要查找的内容进入每个文件夹并运行此脚本,这样可以更好地减少重复项并增加相关数据,但仍然太麻烦。
问题:如何运行 Linux 脚本来搜索如下文件结构中的标签:.xml 文件中感兴趣的标签:
".txt|.csv|.xls"
当前位置:
/dir
感兴趣的文件 1:
/dir/par/ResourceParent.xml
感兴趣的文件 2:
(需要最新的版本号)
/dir/par/ver###/ResourceVer.xml
所需输出文件:
ResourceReport.txt
更新
我发现ls | tail -1
选择了版本号最大的文件夹。所以我认为答案与此有关。
答案1
也许用两个命令...
grep --include="ResourceParent.xml" -r -E '.txt|.csv|.xls' > file
for d in par*; a=("$d"/*); b=($(sort -V <<<"${a[*]}")); grep -HE '.txt|.csv|.xls' "${b[@]: -1}"/*; done >> file
第二个命令将每个目录的内容放入par
按版本号排序的数组中,这样您就可以搜索数组中的最后一项。这似乎有效(我得到了最后一个版本号),并且在我的测试目录结构上只花了几秒钟(第一个命令花费的时间大约是前者的两倍)。
如果您的版本号已填充以便自然排序,则对于第二个命令您可以简单地使用:
for d in par*; a=("$d"/*); grep -HE '.txt|.csv|.xls' "${a[@]: -1}"/*; done >> file
我的意思是,如果您的数字是ver1
ver2
...... ver100
,您将需要对数组进行排序,但如果它们是ver001
...... ver002
,ver100
您将不需要对数组进行排序,因为无论如何它都会处于正确的顺序。
您可能需要用 替换"${b[@]: -1}"/*
。"${b[@]: -1}"/ResourceVer.xml
我没有创建其他文件。您可能还需要用par*
某些内容替换(我认为您说过您在这个级别有大约 100 个目录)。
但也许你想按目录对数据进行排序,以便par
获得
data from par1/ResourceParent.xml
data from par1/ver{latest}/ResourceVer.xml
data from par2/ResourceParent/xml
data from par2/ver{latest}/ResourceVer.xml
您可以对输出文件执行一些文本处理,但这取决于目录的par
命名方式。由于我将它们命名为par1
par2
...par200
sort -V file >> betterfile
将执行该工作,假设文件名没有换行符。
grep -h
您还可以在原始命令中使用(而不是)来修剪文件名-H
(尽管这意味着您无法通过上述方法对数据进行排序),或者通过在最后进行文本处理来修剪文件名,例如,如果您的文件名没有冒号或换行符,这将非常可靠:
sed 's/^[^:]*://' file
-i
您可以在测试后添加标志,将数据写入文件而不是标准输出sed
。
谢谢约翰1024谁的U&L 上的答案提供了一种很好的方法来获取最后一个文件名,而不依赖于解析输出ls
或find
无端循环结构来计算迭代次数。