find + sed,filename输出

时间:2016-05-02 13:26:14

标签: unix sed find

我有目录:D:/Temp,其中有很多带有文本文件的子文件夹。每个文件夹都有" file.txt"。在一些file.txt文件中是一个单词 - "模式"。我想查看有多少个模式单词,并获取该文件路径到该文件.txt:

find D:/Temp -type f -name "file.txt" -exec basename {} cat {}  \; | sed -n '/pattern/p' | wc -l

输出应为:

4
D:/Temp/abc1/file.txt
D:/Temp/abc2/file.txt
D:/Temp/abc3/file.txt
D:/Temp/abc4/file.txt

或类似。

8 个答案:

答案 0 :(得分:2)

您可以使用GNU grep

grep -lr --include file.txt "pattern" "D:/Temp/"

这将返回文件路径。

grep -cr --include file.txt "pattern" "D:/Temp/"

这将返回计数(计算出现的模式而不是文件数)

标志说明:

  • -r使grep以递归方式浏览其目标,然后可以是目录
  • --include <glob>使grep将其递归浏览限制为与<glob>匹配的文件。
  • -l使grep只返回文件路径。另外,它会在遇到模式后立即停止解析文件。
  • -c使grep仅返回匹配数

答案 1 :(得分:0)

我建议您使用两个命令:一个用于查找所有文件:

find ./ -name "file.txt" -exec fgrep -l "-pattern" {} \;

计算他们的另一个:

find ./ -name "file.txt" -exec fgrep -l "-pattern" {} \; | wc -l

答案 2 :(得分:0)

试试这个安全标准的版本:

find D:/Temp -type f -name file.txt -printf "%p\0" | xargs -0 bash -c 'printf "%s" "${@}"; grep -c "pattern" "${@}"' | grep ":[1-9][0-9]*$"

对于file.txt目录和子目录中的每个D:/Temp文件,xargs命令打印文件名和包含pattern的行数({{1 }})。

最终grep -c仅选择计数大于grep ":[1-9][0-9]*$"的文件名。

答案 3 :(得分:0)

以前我用过:

searchFiles=$(find D:/temp -type f -name "file.txt"); [[ ! -z "$searchFiles" ]] && grep -Hc "pattern" $searchFiles

这仅在找到file.txt时才有效。否则,您可以使用以下内容来解释何时找到或找不到两个文件:

D:/Temp/abc1/file.txt 2
D:/Temp/abc2/file.txt 1
D:/Temp/abc3/file.txt 1
D:/Temp/abc4/file.txt 1

此输出看起来更像是:

$('#Stream').attr("src","https://player.twitch.tv/?channel=" + channel);
$('#Chat').attr("src","https://www.twitch.tv/" + channel + "/chat?popout=");

答案 4 :(得分:0)

我会用

find D:/Temp -type f -name "file.txt" -exec dirname {} \; > tmpfile
wc -l tmpfile
cat tmpfile
rm tmpfile

答案 5 :(得分:0)

我正在阅读你的问题的方式,我将回答如下:

  • 部分但不是所有self.layer个文件都包含file.txt
  • 您需要一个导航到带有pattern
  • 的file.txt的路径列表
  • 您希望在每个文件中都计算pattern

有几个选择。 (总是有多种方法可以做任何事情。)

如果您的bash是版本4或更高版本,您可以使用pattern来递归目录:

globstar

这是有效的,因为shopt -s globstar for file in **/file.txt; do if count=$(grep -c 'pattern' "$file"); then printf "%d %s\n" "$count" "${file%/*}" fi done 评估认为失败的if(即零次出现)为FALSE,因此不会打印结果。

请注意,这可能会产生很大影响,因为它会在找到的每个文件上启动单独的grep。较轻的替代方法可能是在fileglob上运行单个grep,并解析结果:

grep

这也取决于bash 4,当然如果你有数百万个文件,你可能会压倒bash的命令行最大长度。这个输出很明显,但如果你的文件名包含冒号,你需要小心解析它。即shopt -s globstar grep -c 'pattern' **/file.txt | grep -v ':0$' 可能不会削减它。

利用grep而不是bash的另一个选项可能是:

cut -d: -f2

这使用GNU grep的grep -r --include 'file.txt' -c 'pattern' ./ | grep -v ':0$' 选项来修改--include的行为(递归)。它应该在Linux,FreeBSD,NetBSD,OSX中运行,但不能在OpenBSD或大多数SVR4(Solaris,HP / UX等)上使用默认的grep。

请注意,我没有测试过这些。不承担任何责任。可能含有坚果。

答案 6 :(得分:0)

如果您的文件名不包含空格,那么您只需要:

tkinter stuff, using callback1()    
...
lots of other code (none to do with tkinter)
...

callback2():    
    do something else
    after(500, callback1)

tkinter stuff using callback2()

some more code (none to do with tkinter)

after(0, callback1)
after(0, callback2)
mainloop()

上面使用的Sub foo4() Selection.Replace " ; ", ";" Selection.Replace " : ", ":" Selection.Replace "; ", ";" Selection.Replace ": ", ":" Selection.Replace " ;", ";" Selection.Replace " :", ":" Selection.Replace "::", ":;" End Sub 的GNU awk。

答案 7 :(得分:-1)

这应该这样做:

find . -name "file.txt" -type f -printf '%p\n' | awk '{print} END { print NR }'