完了する必要がある作業を含む会議契約があります。各契約はキーワードで始まり、次のように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
!)
2番目の実行で使用できるスクリプトを最初に生成し、各担当者に対してこれらの行を自動的に生成する別の方法はありますか?
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
。
新機能は、このタスクを2回目に実行すると、結果*.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
警告する:
タスクを割り当てる人の名前に「タスク」が含まれていないことを確認してください。