Markdown 파일 저장소(일명 Zettelkasten)가 있습니다. 다음 명령을 사용하여 검색합니다 grep -irn 'search request' *.md
. 모든 것이 정상입니다.
그런데 검색된 문자열의 파일 제목과 부제가 출력된 내용을 보고 싶습니다.
예
파일.md
1 # Title
2
3 ## Subtitle
4
5 yada-yada
산출
> grep -irn 'yada' *.md
< file.md:5:Title:Subtitle:yada-yada
grep
파일을 여러 번 검색하지 않고도 이 작업을 수행 할 수 있나요 ?
비슷한 물건기억하다터미널에 이상적입니다.
답변1
아니요, grep은 그렇게 할 수 없습니다. 그러나 awk 또는 Perl을 사용하여 자신만의 사용자 정의 검색 도구를 쉽게 작성할 수 있습니다. 예를 들어
find ./ -name '*.md' -exec awk -v search="yada-yada" '
/^# / { title=$0; sub(/^# /,"",title) };
/^## / { subtitle=$0; sub(/^## /,"",subtitle) };
$0 ~ search { printf "%s:%i:%s:%s:%s\n", FILENAME,FNR,title,subtitle,$0 }' {} +
이는 특정 요구 사항에 맞게 사용자 정의하거나 크게 개선할 수 있는 매우 독창적인 예입니다. .-v search="$1"
"yada-yada"
이것은 Perl로 작성된 약간 더 나은 버전입니다. 이것은 필요하지 않습니다 find
(Perl 고유의파일::찾기모듈) 및 더 나은 옵션 처리를 통해 확장하기가 더 쉬울 수 있습니다(예: 와 유사한 여러 디렉토리 검색을 지원하거나 grep 및 기타 프로그램과 마찬가지로 옵션을 find
추가하거나 대소문자를 구분하지 -i
않거나 -v
역방향 매칭을 지원할 수 있습니다).
#!/usr/bin/perl
use strict;
use File::Find;
# Very primitive argument handling, should use Getopt::Long or
# one of the other Getopt::* modules
my $path = shift; # first arg is dir to search, e.g. './'
my $search = shift; # second arg is regex to search for
find({ wanted => \&wanted, no_chdir => 1}, $path);
sub wanted {
# This uses \z in the regex rather than just $ because
# filenames can contain newlines.
next unless (-f $File::Find::name && /\.md\z/s);
# open the file and "grep" it.
open(my $fh, "<", $File::Find::name) || warn "couldn't open $File::Find::name: $!\n";
my $title = '';
my $subtitle = '';
while(<$fh>) {
chomp;
if (/^# /) {
($title = $_) =~ s/^# //;
} elsif (/^## /) {
($subtitle = $_) =~ s/^## //;
} elsif (/$search/) {
printf "%s:%i:%s:%s:%s\n", $File::Find::name, $., $title, $subtitle, $_;
# uncomment the next line if you want only the first match in
# any given file (i.e. same as '-m 1' with grep):
# close $fh;
}
};
close($fh);
}
실행 예시:
$ ./grep-md.pl ./ yada-yada
./file.md:5:Title:Subtitle:yada-yada
./file2.md:5:Another Title:And Another Subtitle:yada-yada
./sub/dir/several/levels/deep/file3.md:5:Third Title:File Three Subtitle:yada-yada
그런데, File::Find를 사용하여 파일을 찾는 대신 파일을 찾기 위해 작성할 수도 있습니다. find ... -exec
그렇게 하면 아마도 더 좋을 것입니다... 저는 주로 동일한 목표 달성을 보여주기 위해 이 방법을 썼습니다. 궁극적인 목표.