我的文本文件(不幸的是)看起来像这样......
<amar>[amar-1000#Fem$$$_Y](1){india|1000#Fem$$$,mumbai|1000#Mas$$$}
<akbar>[akbar-1000#Fem$$$_Y](1){}
<john>[-0000#$$$_N](0){USA|0100#$avi$$,NJ|0100#$avi$$}
它包含客户名称,后跟一些信息。顺序是......
文本字符串后跟list,set然后是字典
&LT;&GT; [](){}
这不是python兼容文件,因此数据不符合预期。我想处理文件并提取一些信息。
amar 1000 | 1000 | 1000
akbar 1000
john 0000 | 0100 | 0100
1)&lt;&gt;
之间的名称2)列表中的 - 和#之间的数字
3&amp; 4)用逗号分隔字典和|之间的数字和#(这里可以有两个以上的条目)
我愿意使用最适合此任务的任何工具。
答案 0 :(得分:3)
由于语法非常复杂,您可能会找到一个合适的解析器作为最佳解决方案。
#!/usr/bin/env python
import fileinput
from pyparsing import Word, Regex, Optional, Suppress, ZeroOrMore, alphas, nums
name = Suppress('<') + Word(alphas) + Suppress('>')
reclist = Suppress('[' + Optional(Word(alphas)) + '-') + Word(nums) + Suppress(Regex("[^]]+]"))
digit = Suppress('(' + Word(nums) + ')')
dictStart = Suppress('{')
dictVals = Suppress(Word(alphas) + '|') + Word(nums) + Suppress('#' + Regex('[^,}]+') + Optional(','))
dictEnd = Suppress('}')
parser = name + reclist + digit + dictStart + ZeroOrMore(dictVals) + dictEnd
for line in fileinput.input():
print ' | '.join(parser.parseString(line))
此解决方案使用pyparsing库并运行产生:
$ python parse.py file
amar | 1000 | 1000 | 1000
akbar | 1000
john | 0000 | 0100 | 0100
答案 1 :(得分:2)
您可以将所有分隔符添加到awk中的FS
变量并计算字段,例如:
awk -F'[<>#|-]' '{ print $2, $4, $6, $8 }' infile
如果大括号之间有两个以上的条目,您可以使用循环遍历所有字段,直到最后一个,如:
awk -F'[<>#|-]' '{
printf "%s %s ", $2, $4
for (i = 6; i <= NF; i += 2) {
printf "%s ", $i
}
printf "\n"
}' infile
两个命令产生相同的结果:
amar 1000 1000 1000
akbar 1000
john 0000 0100 0100
答案 2 :(得分:2)
您可以使用正则表达式来捕获参数
<强>样品:强>
a="<john>[-0000#$$$_N](0){USA|0100#$avi$$,NJ|0100#$avi$$}"
name=" ".join(re.findall("<(\w+)>[\s\S]+?-(\d+)#",a)[0])
others=re.findall("\|(\d+)#",a)
print name+" | "+" | ".join(others) if others else " "
<强>输出:强>
'john 0000 | 0100 | 0100'
完整代码:
with open("input.txt","r") as inp:
for line in inp:
name=re.findall("<(\w+)>[\s\S]+?-(\d+)#",line)[0]
others=re.findall("\|(\d+)#",line)
print name+" | "+" | ".join(others) if others else " "
答案 3 :(得分:2)
对于您的文件的一行:
test='<amar>[amar-1000#Fem$$$_Y](1){india|1000#Fem$$$,mumbai|1000#Mas$$$}'
替换&lt;使用空字符并删除&gt;之后的所有内容获得名字
echo $test | sed -e 's/<//g' | sed -e 's/>.*//g'
获取所有4位数字符套件:
echo $test | grep -o '[0-9]\{4\}'
用您喜欢的分隔符替换空格
sed -e 's/ /|/g'
这将使:
echo $(echo $test | sed -e 's/<//g' | sed -e 's/>.*//g') $(echo $test | grep -o '[0-9]\{4\}') | sed -e 's/ /|/g'
这将输出:
阿玛尔| 1000 | 1000 | 1000
使用快速脚本得到它:your_script.sh input_file output_file
#!/bin/bash
IFS=$'\n' #line delimiter
#empty your output file
cp /dev/null "$2"
for i in $(cat "$1"); do
newline=`echo $(echo $i | sed -e 's/<//g' | sed -e 's/>.*//g') $(echo $i | grep -o '[0-9]\{4\}') | sed -e 's/ /|/g'`
echo $newline >> "$2"
done
cat "$2"