문자열로 시작하는 디렉토리에서 모든 파일을 찾아 인쇄하려면 쉘 스크립트를 작성해야 합니다 #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}' *