次のファイルがあります(例:
first line sss case-2-hello-world other words
second line other words
third line sss case-1-love-you other words
fourth line other words
fifth line other words
sixth line sss case-6-not-work other words
私はそれを次のように変換したいと思います:
pp:12 pme:4 plan:cpu_bind=hello mem_bind=world
second line other words
pp:6 pme:2 plan:cpu_bind=love mem_bind=you
fourth line other words
fifth line other words
pp:36 pme:12 plan:cpu_bind=not mem_bind=work
まず、パターンのある線を識別しますsss
。第二に、数字を抽出します。第三に、ppとpmeを計算しますpp=number*6 and pme=number*2
。第四に、数字を含む行の単語を分割してcpu_bind
sumsに割り当てますmem_bind
。第五に、一緒に集めてラインを交換します。
たとえば、私は行を識別します
first line sss case-2-hello-world other words
のsss
数字は2です。その後は計算をする必要がありますpp=2*6 pme=2*2
。文字列をcase-2-hello-world
複数の部分に分割し、合計hello
に割り当てますcpu_bind
。最後に、私は得なければならないworld
mem_bind
pp:12 pme:4 plan:cpu_bind=hello mem_bind=world
元の行を交換してください。
注:sss
行のどこにでも表示できますが、一度だけ表示されます。sss
置き換える必要がある行を識別するために使用できる唯一のパターン。行には、数字と異なる数字を含む別の単語があります。パターンはcase-number-cpu_bind-mem_bind
4つの部分で構成されています。その順序は決まっていて吐き出すことができる-
。
答え1
Python(2.x)では:
import sys
pat = 'sss'
for line in open(sys.argv[1]):
if not pat in line:
print line,
continue
case_nr = line.split(pat + ' case-', 1)[1].split('-')[0]
print '**something about case{}**'.format(case_nr)
呼ぶpython script_name.py input.txt > output.txt
答え2
使用に問題がない場合sed
:
sed 's/\(.*\)sss case-\([0-9]*\)-.*/something about case\2/' input.txt
答え3
これは複雑すぎるため、これを行うには完全なプログラミング言語を使用します。たとえば、Perlでは次のようになります。
$ perl -ne 'if(/\ssss\s+/ && /(\S+-\d+-\S+)/){
@F=split(/-/,$1);
print "pp:",
6 * $F[1],
" pme:",2*$F[1],
" plan:cpu_bind=$F[2] mem_bind=$F[3]\n"
}else{print}' file
または少しゴルフをするが、同じアイデアに従ってください。
$ perl -lpe '/\ssss\s+/&&do{/(\S+-\d+-\S+)/;@F=split(/-/,$1);
$_="pp:".6*$F[1]." pme:".2*$F[1]." plan:cpu_bind=$F[2] mem_bind=$F[3]"}' file
これは不正確な可能性があると仮定していることに注意してください(ただし、あなたの質問ではわかりません)。
- それに続く単語が
sss
あなたが興味のある単語であるとします。 - これは、単語が常に
-
サブ単語に分割されると仮定する。 - 単語には常に4つの部分があるとします。
case
最初の部分は数字で、2番目の部分は数字で、合計cpu_bind
に割り当てる必要がある2つの単語がありますmem_bind
。
これらの仮定が正しいと仮定すると、これはスクリプトにコメントを追加するのと同じです。
#!/usr/bin/env perl
## Read the input file line by line
while (<>) {
## If this line matches whitespace (\s), then "sss", then one
## or more whitespace character, identify the string of interest
## by looking for non-whitespace characters (\S+), "-", then
## numbers (\d+), then "-" and more non-whitespace characters and
## save them as $1.
if(/\ssss\s+/ && /(\S+-\d+-\S+)/){
## Split the word captured above into the @F array
## by cutting it on "-"
@F=split(/-/,$1);
## Start printing.
print "pp:",
## 6 * the 2nd element in the array (the number)
6 * $F[1],
" pme:",2*$F[1],
## The third element ($F[2]) is the 1st word
## and the fourth element ($F[3]) is the 2nd word.
" plan:cpu_bind=$F[2] mem_bind=$F[3]\n"
}
## If this line does not match "sss", print it.
else{print}
}
答え4
私が理解したように説明すると、次のようになります。
sed "/sss/{s/case1.*$/$case1;s/case2.*/$case2;s/case3.*/$case3}"
ただし、行全体を置き換える必要がある場合、または逆に単語を最後に保持する必要がある場合は、コメントでお問い合わせください。簡単に提供されます。