我想在Groovy中的制表符分隔文件中阅读...
inputFile.eachLine { rawLine ->
def line = rawLine.split('\t')
def orderId = line[0]
但我不想记住哪个字段在哪个列号,我宁愿做类似......
的事情 def orderId = line['ORDERID']
现在,如果我尝试这个,它会给出一个例外..
groovy.lang.MissingPropertyException:
Exception evaluating property 'ORDERID' for java.util.Arrays$ArrayList
我认为是因为我在每个记录中都是以列表而不是地图的形式阅读。那么如何将这个文件作为地图阅读呢?
答案 0 :(得分:1)
鉴于此制表符分隔文件:
-h
以下脚本使用Groovy 2.4.5和groovycsv(建议为tim_yates;我恰好正好使用它):
"City" "Country" "Year"
Paris France 2016
Toronto Canada 2010
和@Grab('com.xlson.groovycsv:groovycsv:1.1')
import static com.xlson.groovycsv.CsvParser.parseCsv
def file = args[0]
def text = new File(file).getText()
def data = parseCsv(text, separator: '\t')
data.each { line ->
println "city: " + line["City"]
println "country: " + line["Country"]
println "year: " + line["Year"]
}
产生:
groovy MyScript.groovy my_file.csv
答案 1 :(得分:0)
有点死灵,但是如果有人对“手工”方法感兴趣,这会让您入门。我意识到上述库可能是更好的,所以这里出于教育目的。
如果发生以下情况,它将中断:
FixtureMinion
是我的测试环境中的本地类,使用类加载器显然不是加载文件的唯一方法。
在某些测试中,当我想要看起来像来自数据库的数据而不是实际上来自数据库的数据时,可以使用它。 YMMV。
static List<Map<String, String>> listOfMapFromTabSeparatedFile(String resourcFile) {
// The list where the maps are "accumulated"
List<Map<String, String>> accumulator = []
URL fileLocation = FixtureMinion.class.getClassLoader().getResource(resourcFile)
new File(fileLocation.toURI()).withReader { reader ->
// get the columns
List<String> columns = splitOnTabs(reader.readLine())
reader.eachLine { line ->
List<String> record = splitOnTabs(line)
assert columns.size() == record.size()
// magic happens
accumulator << [columns, record].transpose().collectEntries { it }
}
}
accumulator
}
static List<String> splitOnTabs(String stringToSplit) {
stringToSplit.split("\t", -1) as List<String>
}
进一步,解释“魔术”激发了普通外壳
15:38 $ groovysh
Groovy Shell (2.4.9, JVM: 1.8.0_181)
Type ':help' or ':h' for help.
-----------------------------------------------------
groovy:000> col = ['a','b','c']
===> [a, b, c]
groovy:000> rec = ['x','y','z']
===> [x, y, z]
groovy:000> [col, rec].transpose()
===> [[a, x], [b, y], [c, z]]
groovy:000> [col, rec].transpose().collectEntries {it}
===> [a:x, b:y, c:z]
transpose
在这里创建对,collectEntries
将它们变成地图。