첫 번째 줄에서 패턴 검색 후 파일명만 출력 (grep, head 이용)

첫 번째 줄에서 패턴 검색 후 파일명만 출력 (grep, head 이용)

그래서 저는 초보자이고 다음 주에 프로젝트 마감일이 있습니다. #!/bin/bash첫 번째 줄에 포함된 파일의 파일 이름 만 인쇄해야 합니다 . 지금까지 나는 이것을 시도했다

head -n 1 $filename | grep -l "pattern"

하지만 대신 실행하면 파일 이름이 표시됩니다.

(standard input)

앞서 말했듯이 저는 초보자이고 지금까지는 간단한 명령에 익숙합니다. 그래서 내가 어디를 엉망으로 만들고 있는지, awk.

for fis in  find -perm -a+x -name "*.sh" -type f
do
head -n 1 $fis | grep -l "#!/bin/bash"
done

답변1

GNU에서는 입력이 stdin에서 오는 경우 grep옵션을 사용하여 레이블/파일 이름을 설정할 수 있습니다.--label

-exec명령 대체와 함께 외부 루프를 사용하는 대신 이 작업을 사용하여 파일 이름을 반복하고 명령을 실행하는 작은 스크립트를 시작할 수 있습니다.

find -perm -a+x -name "*.sh" -type f -exec sh -c '
  for fis; do
    head -n1 "$fis" | grep --label="$fis" -Fl "#!/bin/bash"
  done
' sh {} +

고정 문자열을 찾고 있기 때문에 해당 -F옵션을 추가했습니다 .grep

답변2

나는 당신이 awk를 블랙리스트에 올렸다는 것을 알고 있지만 도움을 구하는 문제에 직면한 다른 사람을 위해 .sh첫 번째 줄에 포함된 실행 파일의 이름을 인쇄하는 매우 효율적인 방법은 다음과 같습니다.#!/bin/bash

find . -perm -a+x -name '*.sh' -type f -exec \
    awk 'NR == 1{ if ($0 == "#!/bin/bash") print FILENAME; exit }' {} \;

#!/bin/bash또는 추가 제한 없이 첫 번째 줄에 파일 이름을 인쇄하려면 -perm-name옵션을 제거하세요.

find . -type f -exec awk ...

답변3

find . -perm -a+x -name '*.sh' -type f |
    while IFS= read -r file; do
        test -f "$file" || continue
        if head -n 1 "$file" | grep -qFx '#!/bin/bash'; then
            echo "$file"
        fi
    done

답변4

나는 이것이 파티에 매우 늦었다는 것을 알고 있지만 나는 훌륭한 결과를 얻기 위해 똑같은 일을 해왔습니다.

find . -perm -a+x -name "*.sh" -exec \
    bash -c 'grep -q "pattern" < <(head -n 1 "$1")' _ {} \; -printf '%p\n'

-q이 플래그는 표준 출력에 쓰는 것을 방지하여 파일 이름( %pfrom )을 인쇄할 수 있도록 허용하는 것으로 이해됩니다 find -printf.

관련 정보