각 파일의 첫 번째 줄의 첫 번째 문자가 공백, 탭 또는 줄 바꿈인 디렉터리 트리에서 모든 파일을 반복적으로 찾는 방법은 무엇입니까?

각 파일의 첫 번째 줄의 첫 번째 문자가 공백, 탭 또는 줄 바꿈인 디렉터리 트리에서 모든 파일을 반복적으로 찾는 방법은 무엇입니까?

예를 들어:

a.txt와 b.txt라는 두 개의 파일이 있습니다.

a.txt

line 1
line 2

b.txt

 line 1
line 2

이 경우 첫 번째 줄의 첫 번째 문자가 공백, 탭 또는 줄바꿈 문자이기 때문에 b.txt가 목록에 나타나야 합니다.

답변1

이 시도:

find . -type f -exec awk 'NR==1 && /^\s/{print FILENAME}' {} \;

또는 사용4:

shopt -s globstar
awk 'NR==1 && /^\s/{print FILENAME} **/*

답변2

그리고 zsh:

starts_with_space() {
  local c
  read -ku0 c < ${1-$REPLY} && [[ $c = [$' \t\n'] ]]
}
printf '%s\n' **/*(D.L+0+starts_with_space)
  • D도트 파일(숨겨진 파일)을 포함하고 다음과 같은 숨겨진 디렉터리로 이동합니다 find.
  • .일반 파일만(예: find's' -type f)
  • L+0:비어 있지 않은 파일만(예: find's' -size +0c)
  • +starts_with_spacetrue를 반환 하는 항목만 해당됩니다 starts_with_space.

이 작업의 이점 중 하나는 find정렬된 파일 이름 목록을 제공한다는 것입니다. 각 파일에서 한 문자만 읽습니다(멀티바이트 문자 집합이 있는 로케일에서는 1바이트 이상일 수 있음).

답변3

올바른 방법은 다음과 같이 하는 것입니다.find+awk주문하다:

find . -type f -size +0c -exec awk '{ exit (/^[[:space:]]/? 0 : 1) }' {} \; -print

exit문을 사용하면 awk현재 규칙의 실행이 즉시 중지되고 입력 처리가 중지됩니다. 종료문은 다음과 같이 작성됩니다.

exit [return code]

종료 매개변수가 제공되면 해당 값은 프로세스의 종료 상태 awk코드 로 사용됩니다.

find~의-printawk프로세스가 종료 상태를 제공하는 경우에만 작업이 수행됩니다.0


보다 단순화된 접근 방식은 다음과 같습니다.

find . -type f -size +0c -exec awk '{ exit (!NF? 0 : 1) }' {} \; -print

답변4

솔루션 및 awk최종.

GNU 사용 sed(명시적 종료 상태로 스크립트 종료 지원 sed):

find . -type f -size +0c -exec sed -n '1{/^[^[:blank:]]/q 1};q' {} ';' -print

이렇게 -size +0c하면 완전히 비어 있는 파일이 보고되지 않습니다.

현재 디렉터리에 문제의 두 파일과 c.txt첫 번째 줄이 비어 있는 추가 파일이 포함되어 있는 경우 다음이 생성됩니다.

./b.txt
./c.txt

GNU sed스크립트:

1{
    /^[^[:blank:]]/q 1
}
q

라인 1의 경우 라인의 첫 번째 문자가 비어 있지 않은지(공백이나 탭이 아닌) 확인하고, 그렇다면 q 1종료 상태 1( )로 종료됩니다. 그렇지 않으면 종료 상태 0(마지막 상태 q)으로 종료됩니다.

빈 첫 번째 줄은 일치하지 않으므로 /^[^[:blank:]]/이 경우는 올바르게 처리됩니다.

sed종료 상태가 0인 상태로 종료하면 -print파일의 경로 이름이 표준 출력으로 인쇄 됩니다 find.


동등한 것이지만 다음을 사용하면 awk(무엇 awk이든 가능합니다):

find . -type f -size +0c -exec awk '/^[^[:blank:]]/ { e=1 } { exit e }' {} ';' -print

관련 정보