在整个目录中搜索文本文件中的特定行

在整个目录中搜索文本文件中的特定行

假设您有一个根目录,并且您想要浏览该目录中的每个子目录并查找名为“data.txt”的任何文本文件。然后,您希望从所有以“Results:”开头的数据文本文件中提取任何行。您想要打印任何具有名为“data”的文本文件的目录并打印任何结果行。例如,如果目录结构是:

root
directory1:
  data.txt
directory2:
  // no data.txt here
directory3:
  data.txt

输出应该是:

directory1
Results: .5
directory3
Results: .6
Results: .7

到目前为止,这是我的代码,但它不起作用:

for d in */; do
> if [[ -f "data.txt" ]]
> then
> echo “$d”
> grep -h “Results:" $data.txt
> fi
> done

当我运行这段代码时,没有任何打印。我认为这个解决方案基本上是正确的,但我遇到了一些语法问题。有人知道该怎么办吗?

答案1

这是您的原始代码,其中包含有关其中可能存在问题的注释:

#!/bin/bash
# That first line is called shebang, if you're interested

for d in */; do
    # 1. You have to check for data.txt in specific location,
    #    so prepend $d directory from your loop to the path:
    if [[ -f "$d/data.txt" ]]
    then
        # 2. “ and ” are good for casual text, but program code uses simple quotes - "
        # 3. You print the name of the every directory you loop over,
        #    even while there are no "Results:" lines there
        echo "$d"
        # 4. Again, $data.txt is weird path - it will result in
        #    directory name with "ata.txt" in your example,
        #    e.g. directory1/ata.txt
        # -  Minor note: better to use regexp's meta-character "^"
        #    to match "Results:" only in the beginning of the lines
        grep -h "^Results:" "$d/data.txt"
    fi
done

该脚本产生下一个输出:

directory1/
Results: .5
directory3/
Results: .6
Results: .7

如果你想解决第三个问题,那么你应该这样做:

#!/bin/bash

for d in */; do
    if [[ -f "$d/data.txt" ]]; then
        # First, search for the results
        RESULTS=$(grep -h "^Results:" "$d/data.txt")
        # Second, output directory name (and the results)
        # only if the grep output is not empty:
        if [[ -n "$RESULTS" ]]; then
            echo "$d"
            echo "$RESULTS"
        fi
    fi
done

# Produces same output

其他需要改进的部分是支持递归目录来查找诸如directory/subdirectory/data.txt之类的文件:

#!/bin/bash
# Allow recursive matches
shopt -s globstar

# Loop over the directories recursively:
for dir in **/; do
# ...
# rest of the code

最后,如果您想输出不带尾部斜杠的目录名称(如示例所示),则:

# Instead of
echo "$d"
# Print $d without "/" suffix:
echo "${d%/}"

生成的脚本:

#!/bin/bash
shopt -s globstar

for d in **/; do
    if [[ -f "$d/data.txt" ]]; then
        RESULTS=$(grep -h "^Results:" "$d/data.txt")
        if [[ -n "$RESULTS" ]]; then
            echo "${d%/}"
            echo "$RESULTS"
        fi
    fi
done

会产生(我添加了示例子目录):

directory1
Results: .5
directory3
Results: .6
Results: .7
directory4/subdir
Results: .9

相关内容