질문

질문

질문

파일로 가득 찬 git 저장소가 있는데 대부분은 텍스트입니다.

있는지 알고 싶습니다.

  • n다음으로 끝나는 파일의 코드 줄.py
  • m다음으로 끝나는 파일의 코드 줄.md
  • o다음으로 끝나는 파일의 코드 줄.yaml
  • p파일의 코드 줄확장자 없음

노트:

  • 재귀적으로 실행하고 싶습니다. 폴더 내부를 확인하세요.
  • .git최상위 폴더의 디렉터리를 제외하고 싶습니다.
  • 바이너리 파일을 무시하는 것이 가능할 것 같습니다(확장자가 없는 일부 텍스트 파일과 확장자가 없는 일부 바이너리 파일이 있습니다).
  • 대소문자를 구분하고 싶습니다. 그룹.csv.CSV
  • 빈 줄(또는 빈 줄만)을 무시하고 싶습니다.
  • 나와 같은 파일이 있는 경우 myfile.yaml.j2그룹 .j2또는 .yaml.j2.

답변1

이 시도:

find ./ -not -path "./.git/*" -type f -exec wc -l {} + |
    awk '{print tolower($0)}' |
    sed -e '$ d' | 
    sed -e "s#/.*/##g" |
    sed -e "s/\./ \./g" |
    awk '
        { if ( NF <= 2 ) { count["none"] += $1 } else { count[$NF] += $1 } }
        { next }
        END { for (group in count) printf("%d%s%s\n", count[group], OFS, group) }
    ' |
    sort -n

분할:

  • find ./이 디렉터리에서 개체를 반복적으로 검색합니다.
  • -not -path "./.git/*"들어오지 못하게 하다.git
  • -type f디렉토리 대신 파일
  • -exec wc -l {} +각 파일에 대해 단어 개수 유틸리티( wc)를 실행합니다. 여기에는 빈 줄이 포함되어 있으므로 질문의 모든 요구 사항을 충족하지 않습니다.
  • awk '{print tolower($0)}'소문자로 되다
  • sed -e '$ d'모든 파일의 줄 합계인 마지막 줄을 제거합니다.
  • sed -e "s#/.*/##g"예를 들어, 삭제된 파일의 경로는  확장자가 아니라 확장자가 a/something.egg/blah없는 것으로 계산되어야 합니다..egg/blah
  • sed -e "s/\./ \./g"파일 확장자가 자체 단어가 되도록 검색/ .바꾸기.
  • awk '{ if ( NF <= 2 ) { count["none"] += $1 } else { count[$NF] += $1 } } { next } END { for (group in count) printf("%d%s%s\n", count[group], OFS, group) }'이것은 큰 문제입니다.  awk 강력하지만 매우 날카롭지는 않습니다.
    • count사전이다
    • if (NF <= 2)"단어"가 3개 미만인 경우 확장자가 없습니다.
    • count["none"] += $1사전의 요소를 증분합니다. 키는 문자열 리터럴입니다 none. 첫 번째 단어인 파일의 줄 수를 추가하여 증분합니다.$1
    • count[$NF] += $1사전에 요소를 추가합니다. 키는 $NF(줄의 마지막 단어)이며 확장자는 $1(줄의 첫 번째 단어)는 파일의 줄 수입니다.
    • { next }모든 행에 대해 반복
    • for (group in count)루프 for, 인라인
    • printf(...)number extension예를 들어  출력 문자열의 형식을 ;로 지정합니다 123 .abc(으로 끝나는 파일에 123줄이 있는 경우 .abc).
  • sort -n결과를 오름차순으로 정렬합니다. -n문자열이 아닌 숫자로 정렬하는 것을 의미합니다.

답변2

내가 올바르게 이해하고 테스트가 양호하다면 다음을 권장합니다(숨겨진 디렉터리와 파일을 건너뛰고 싶다고 가정하고 그렇지 않은 경우 알려주시기 바랍니다).

shopt -s globstar

declare -A arr
for f in test/**; do
  # if a directory, skip
  [[ -d "$f" ]] && continue
  lines=0
  # strip the extension
  ext="${f##*.}"
  # convert it to lowercase
  ext="${ext,,}"
  # if no dot in the name, extension is "empty"
  [[ ! $(basename "$f") =~ \. ]] && ext="empty"
  # count the lines
  lines=$(wc -l "$f"| cut -d' ' -f1)
  # if lines equals to 0, skip
  [[ $lines -eq 0 ]] && continue
  # append the number of line to the array
  lines=$(( "${arr[$ext]}"+$lines ))
  arr[$ext]=$lines 
done

# loop over the array
for n in ${!arr[@]}; do
  echo "files $n: total lines ${arr[$n]}"
done

출력(예제 파일에서):

files yaml: total lines 3
files md: total lines 3
files empty: total lines 4
files csv: total lines 6
files py: total lines 5

답변3

이해하기 쉽도록 함수별로 나누었습니다.

#!/bin/bash

# For the next two functions, we will use "-print0", which will print out \0 instead of \n.
# This will help prevent whitespace problems when piping the filenames into xargs.

find_extension()
{
    find "$1" -type f -name "*.$2" -print0 2>/dev/null
}

find_no_extension()
{
    find "$1" -type f -regex '^.*/[^.]+$' -print0 2>/dev/null
}

concat_files()
{
    xargs -0 cat
}

delete_empty_lines()
{
    sed -E '/^[[:space:]]*$/d'
}

line_count_of_files()
{
    concat_files | delete_empty_lines | wc -l
}

print_usage()
{
    echo "Usage: $0 [EXTENSION]... [SEARCH_DIRECTORY]";
}

NUMBER_OF_EXTENSIONS=$(($# - 1))
SEARCH_DIR="${*: -1}"

if [ $# -lt 2 ];
then
    echo "Not enough parameters.";
    print_usage;
    exit 1;
fi

if ! [ -d "$SEARCH_DIR" ];
then
    echo "$SEARCH_DIR does not exist, or is not a directory."
    print_usage;
    exit 1;
fi

for EXTENSION in "${@:1:$NUMBER_OF_EXTENSIONS}";
do
    printf ".$EXTENSION: %s\n" $(find_extension "$SEARCH_DIR" "$EXTENSION" | line_count_of_files)
done


printf "No extension: %s\n" $(find_no_extension "$SEARCH_DIR" | line_count_of_files)

이는 검색하려는 파일 확장자를 지정할 수 있는 일반적인 스크립트에 가깝습니다. 하지만 항상 확장자가 없는 파일을 검색합니다.

파일에 저장하고 실행 권한을 부여한 후 PATH에 넣어야 합니다. 이름을 count_lines.sh로 지정한다고 가정해 보겠습니다. 다음과 같이 호출할 수 있습니다 count_lines.sh py md yaml ~/Code. 그러면 디렉토리에서 ~/Code, 및 로 끝나는 파일과 확장자가 전혀 없는 파일을 검색합니다. 검색할 확장자를 원하는 만큼 선택할 수 있습니다. 최소한 하나가 있는지 확인하세요..py.md.yaml

관련 정보