텍스트 파일의 특정 줄에 대한 전체 디렉터리 검색

텍스트 파일의 특정 줄에 대한 전체 디렉터리 검색

루트 디렉터리가 있고 해당 디렉터리 내의 모든 하위 디렉터리를 탐색하여 "data.txt"라는 이름의 텍스트 파일을 찾으려고 한다고 가정합니다. 그런 다음 "결과:"로 시작하는 데이터 텍스트 파일에서 모든 행을 추출하려고 합니다. "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

개선이 필요한 다른 부분은 디렉토리/하위 ​​디렉토리/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

관련 정보