2017-10-14 64 views
0

我试图从在时尚格式,如文本文件中读取列(其中你有一个关键字列和相关的密钥值):读词/短语与空间

蜜桔12

榴莲5

苹果3.5

使用读取功能,我可以在阅读栏目,但只有当列基本上每一个字。在上述示例中,我不确定要做什么,因为第二项是两个单词,但我想将它作为一个单词存储。

回答

1

随着一个正则表达式:

while read -r line; do 
    [[ $line =~ ^(.*)\ (.*)$ ]] && echo "${BASH_REMATCH[1]}|${BASH_REMATCH[2]}" 
done < file 

输出:

 
tangerine|12 
durian fruit|5 
apple|3.5 

${BASH_REMATCH[1]}包含第一列和${BASH_REMATCH[2]}秒柱。

+0

很好,谢谢!你能简单介绍一下你所使用的正则表达式格式吗?我总体上知道一些正则表达式,但它看起来有点像巨无霸。 – Yuerno

+0

后续问题:是否可以使用循环迭代BASH_REMATCH 1或2中的每个条目?我试图使用一个for循环,使用一个短语,例如:“for i in”$ {BASH_REMATCH [1]“”,但它只获取列表中的最后一个条目。 – Yuerno

+0

我的语言技能还不够。 '\'仅用于转义空格字符。正则表达式从左到右进行处理。 '*'很贪婪,并尽力捕捉。对于第二个问题:我会省略双引号。 – Cyrus

2

您应该使用除空格以外的其他名称来区分名称和计数,如选项卡。然后,你可以使用

while IFS=$'\t' read -r fruit count; do 
    echo "Fruit: $fruit" 
    echo "Count: $count" 
done < data.txt 

如果不能做出改变,你可以阅读每一行到一个数组中,并重新加入第一组列。不过,这会失去任何特定的空白区域。

while read -a data; do 
    fruit=${data[*]:0:${#data[@]}-1} 
    count=${data[@]:${#data[@]}-1} 
done < data.txt 

无论采用哪种方式,都可以在循环内建立水果名称和计数的数组。

while ...; do 
    fruits+=("$fruit") 
    counts+=("$count") 
done << ... 

for ((i=0; i<${#fruits[@]}; i++)); do 
    echo "Fruit #$i: there are ${counts[i]} ${fruits[i]}(s)" 
done 
+1

使用Bash 4.3或更新版本,您可以使用'$ {data [-1]}'访问最后一个元素。 –

+0

我总是忘记什么时候和什么让你使用负指数。 – chepner

+0

这也很好,谢谢!笔者想到,任何特定的白色空间都会丢失,例如,“榴莲果”会变成“榴莲果”,但它运行良好,似乎保持了空间。我有和第一个答案一样的问题;我可以遍历水果的内容并将其作为数组来计数吗? – Yuerno