我有一个这样的文件(这是一个示例,该文件包含更多这样的行):
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
和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
有四个部分。它的顺序是固定的,可以被吐出-
。
答案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
第一个部分是数字,第二个部分是数字,然后是两个应分配给cpu_bind
和 的单词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}"
但如果您需要替换整行,或者相反,最后保留单词,只需在评论中询问 - 这很容易提供。