진주

진주

완수해야 할 작업이 포함된 회의 계약이 있는데, 각 계약은 키워드로 시작하여 다음과 같이 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그룹화를 사용할 수 있다는 점에 유의하세요.

이전된 포인트https://stackoverflow.com/questions/14679479/how-can-write-the-multiple-files-with-sed-from-pattern-matched

답변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

진주

Slurptask.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

경고하다:

작업을 할당하는 사람의 이름에 "작업"이 포함되어 있지 않은지 확인하세요.

관련 정보