완수해야 할 작업이 포함된 회의 계약이 있는데, 각 계약은 키워드로 시작하여 다음과 같이 TODO
끝납니다 .D/nameOfAssignee
Meeting 2017/03/22
some stuff
TODO task for philipp D/philipp
some more stuff
TODO task for jane D/jane
TODO task for joe D/joe
some other stuff TODO Another
task for Philipp
D/philipp
still
more
stuff
TODO Yet another
task for jane D/jane
이제 파일을 얻고 싶습니다 philipp.txt
.
task for philipp
Another task for Philipp
그리고 파일 jane.txt
:
task for jane
Yet another task for jane
그리고 파일 joe.txt
:
task for joe
나는 다음을 사용하여 이 작업을 수행합니다 sed
.
sed -n '/TODO/!d
:l
/D\//bw
N
bl
:w
s/.*TODO *//
s/\n/ /g
s_ *D/philipp__w philipp.txt
s_ *D/joe__w joe.txt
s_ *D/jane__w jane.txt
' tasks.txt
이것은 작동하지만 가능한 모든 할당자에 대해 스크립트에서 동일한 줄을 사용해야 하므로 짜증나기 시작합니다. 문서에서 파일 이름에 정규식 일치 하위 문자열을 사용하는 방법을 찾을 수 없습니다. 예를 들면 다음과 같습니다.
s_ *D/\(.*\)__w \1.txt
(이것은 작동하지 않습니다! 모든 것이 이름이 지정된 파일에 기록됩니다 \1
!)
두 번째 실행에서 사용할 수 있는 스크립트를 먼저 생성하고 각 담당자에 대해 이러한 줄을 자동으로 생성할 수 있는 또 다른 방법이 있습니까?
sed
아니면 내가 에서 이와 같은 작업을 수행해야 하는 잘못된 도구 입니까 python
?
답변1
원하는 것을 수행할 수 있는 방법이 있지만 이는 GNU sed에서만 작동합니다.
sed -rn '/TODO/!d
:l
/D\//bw
N
bl
:w
s/.*TODO *//
s/\n/ /g
s_(.*) *D/(.*)_echo \1 >> \2.txt_e
' tasks.txt
그 비밀은 e
패턴 공간의 내용을 쉘 코드로 실행하는 교체 명령의 특수 스위치에 있습니다. 또한 -r
그룹화를 사용할 수 있다는 점에 유의하세요.
답변2
이 시도...
awk '{F=0;for(i=2;i<=NF;i++){if($(i-1)~/TODO/){F=1}if(F){printf("%s ",$i)}}printf("\n")}' RS="D/" tasks.txt | awk '{print > $NF".txt"}'
답변3
정말 스크립트를 작성해야 할 것 같아요. 적어도 sed 변환의 긴 목록보다 유지 관리하고 문서화하는 것이 더 쉽습니다(그러나 내 의견은 동의하지 않을 수도 있습니다).
다음은 Perl 제안입니다:
#!/usr/bin/perl -n
#
sub printTodo {
my ($todo,$person) = @_;
my $file;
open($file, ">>$person.txt");
print $file "$todo\n";
close($file);
}
if (/TODO (.*)D\/(\S*)/) {
printTodo($1,$2);
} elsif (/TODO (.*)/) {
$found = "$1 ";
} elsif (/(.*)D\/(\S*)/) {
$found .= $1;
printTodo($found,$2);
$found = undef;
} elsif ($found) {
chomp $_;
$found .= "$_ ";
}
이 스크립트를 로 저장하고 script.pl
회의 보고서를 로 저장한다고 가정하면 meeting
다음과 같이 호출할 수 있습니다 ./script.pl < meeting
.
답변4
진주
Slurp
task.txt로 시작하는 문자열을 살펴보고 TODO
가장 가까운 문자열을 찾으면 D/
필요할 경우 줄바꿈을 건너뛸 수도 있습니다. m//s
.
새로운 기능은 이 작업을 두 번째로 실행하면 결과 *.txt
파일이 추가되지 않고 회전할 때마다 다시 시작된다는 것입니다. 따라서 구조적으로 폭주 증후군에 직면하지 않습니다.
perl -MFatal=open -l -0777ne '
do{open my $fh, $h{$2}++ ? ">>" : ">", "$2.txt"; print $fh $1 =~ y/\n/ /rs}
while m|\bTODO\s*(.+?)\s*D/(\S+)|sg' tasks.txt
sed+ed
이와 같은 상황에서 흔히 발생하는 것처럼 우리는 ed
출력을 얻기 위해 코드를 동적으로 작성합니다. 이 경우의 참신함은 ed
코드가 실행될 데이터 파일 자체가 동일한 입력에서 동적으로 생성된다는 것입니다.
따라서 data.txt에 데이터+코드가 있는 것처럼 이 데이터도 분리된 다음 입력으로 모아서 ed
출력을 생성합니다 ed
.
sed -n '
/TODO/!d
:l
/D\//bw
N
bl
:w
s/.*TODO *//
s/\n/ /g
#<----------------------- ORIG --------------------->#
H;s| *D/.*||w /tmp/data.txt
g;s/.*\n//;x;s/\(.*\)\n.*/\1/;x
G;s/\n/&&/
h
/ *D\/\(.*\)\n\(\(.*\n\)\{0,\}\)\1\n/!{
s/.*[^ ] *D\/\(.*\n\)\n/\1/
x
s/\n\n.*//
s|\(.*[^ ]\) *D/|/\1/w |;s|$|.txt|p;$!d;s/.*/q/p;q
}
g
s/\n\n.*//
s|\(.*[^ ]\) *D/|/\1/W |;s|$|.txt|p;$!d;s/.*/q/p;q
' tasks.txt | ed -s - /tmp/data.txt
경고하다:
작업을 할당하는 사람의 이름에 "작업"이 포함되어 있지 않은지 확인하세요.