![파일의 첫 번째 줄에 특정 문자열이 포함되어 있는지 확인하는 방법은 무엇입니까? [복사]](https://linux55.com/image/141804/%ED%8C%8C%EC%9D%BC%EC%9D%98%20%EC%B2%AB%20%EB%B2%88%EC%A7%B8%20%EC%A4%84%EC%97%90%20%ED%8A%B9%EC%A0%95%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%98%EC%96%B4%20%EC%9E%88%EB%8A%94%EC%A7%80%20%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F%20%5B%EB%B3%B5%EC%82%AC%5D.png)
문자열로 시작하는 디렉토리에서 모든 파일을 찾아 인쇄하려면 쉘 스크립트를 작성해야 합니다 #include
. 이제 다음을 통해 파일에 문자열이 있는지 확인하는 방법을 알았습니다.
for f in `ls`; do
if grep -q 'MyString' $f; then:
#DO SOMETHING
fi
그런데 첫 번째 행에 어떻게 적용할 수 있나요? 첫 번째 줄에 대한 변수를 만들고 그것이 시작하는지 확인하려고 생각했지만 #include
이를 수행하는 방법을 잘 모르겠습니다. 명령 을 시도했지만 read
변수를 읽을 수 없습니다.
이 문제를 해결하는 다른 방법을 듣고 싶습니다. 어쨌든, 첫 번째 줄이 #include
문자열을 포함하는지가 아니라 로 시작하는지 확인해야 한다는 점을 기억하세요 . 이것이 내가 다음과 같은 문제를 발견한 이유입니다.첫 번째 줄이 특정 패턴과 일치하는 경우에만 파일 내용을 인쇄하는 방법은 무엇입니까?
https://stackoverflow.com/questions/5536018/how-to-print-matched-regex-pattern-using-awk
그들은 정확히 도움이 되지 않았습니다.
답변1
첫 번째 줄이 sed로 시작하는지 확인하는 것은 쉽습니다 #include
(GNU 및 AT&T).
sed -n '1{/^#include/p};q' file
또는 단순화된(및 POSIX 호환):
sed -n '/^#include/p;q' file
#include
파일이 첫 번째 줄에 포함된 경우에만 출력됩니다. 이렇게 하면 첫 번째 줄만 읽어서 확인할 수 있으므로 속도가 매우 빨라집니다.
따라서 모든 파일에 대한 쉘 루프(sed 사용)는 다음과 같아야 합니다.
for file in *
do
[ "$(sed -n '/^#include/p;q' "$file")" ] && printf '%s\n' "$file"
done
만약에pwd에는 파일만 있습니다(디렉토리 없음).
파일의 모든 줄을 인쇄해야 하는 경우 게시된 첫 번째 코드(GNU 및 AT&T 버전)와 유사한 솔루션을 사용할 수 있습니다.
sed -n '1{/^#include/!q};p' file
또는 (BSD 호환 POSIX 버전):
sed -ne '1{/^#include/!q;}' -e p file
또는:
sed -n '1{
/^#include/!q
}
p
' file
답변2
for file in *; do
[ -f "$file" ] || continue
IFS= read -r line < "$file" || [ -n "$line" ] || continue
case $line in
("#include"*) printf '%s\n' "$file"
esac
done
파일 이름 대신 파일 내용을 인쇄하려면 printf
명령을 cat < "$file"
.
awk
확장 기능을 지원 nextfile
하고 일반적이지 않은 파일을 열 때 발생할 수 있는 부작용에 대해 신경 쓰지 않는 경우 :
awk '/^#include/{print substr(FILENAME, 3)}; {nextfile}' ./*
위에 우리는문자가 포함된 파일 이름 (또는 이름이 이라는 파일 이름 ) 과 관련된 문제를 방지하기 ./
위해 나중에 제거할 접두사를 추가합니다 .FILENAME
=
-
.
를 사용하면 대신 일반 파일(또는 위 방법 과 같이 일반 파일에 대한 심볼릭 링크)을 에 전달할 zsh
수 있습니다 ../*
./*(-.)
[ -f ... ]
awk
또는 이름 대신 파일 내용을 인쇄합니다.
awk 'FNR == 1 {found = /^#include/}; found' ./*
(이것은 휴대용입니다).
답변3
for file in *
do
[ -f "$file" ] && head -n 1 < "$file" | grep -q '^#include' && cat < "$file"
done
-q
이 옵션을 활성화하면 오류 grep
가 발생하더라도 0 상태로 종료됩니다.
답변4
이 질문은 bash 및 sed 솔루션이 매우 복잡하지만 (GNU) awk를 사용하면 작업이 훨씬 간단해지는 완벽한 예입니다.
gawk 'FNR==1 && /^#include/{print FILENAME}{nextfile}' *