我的问题将来自this。我正在编写一个简单的.ksh文件,从.csv文件中读取单个列,然后将输出打印到屏幕上:
fname=($(sed 1d myfile.csv | cut -d, -f2))
# loop through these names
for i in ${fname[@]};
do echo "$i"
done
我现在的问题是我希望fname中的每个条目都是一个可以是两个单词的字符串。例如,如果csv文件有一列
data
data 1
data 2
我希望fname成为:
data
data 1
data 2
目前正在返回:
data
data
1
data
2
是否可以调整我的代码来执行此操作?
我使用awk的版本是:
fname=($(awk -F "\"*,\"*" '{print $2}' "myfile"))
# loop through these names
for i in ${fname[@]};
do echo "$i"
done
答案 0 :(得分:1)
awk回答
$ cat myData
c1,data,c3
c1,data 1,c3
c1,data 2,c3
# demo-solution
awk -F, -v OFS=, '{print $1, "\"" $2 "\"", $3 }' myDat
**output**
c1,"data",c3
c1,"data 1",c3
c1,"data 2",c3
如果您真的只需要第二个字段,只需从打印行中删除$1,
和, $3
,即
#exact output solution
awk -F, '{print "\"" $2 "\"" }' myDat
**output**
"data"
"data 1"
"data 2"
这个答案也可以用于" in-line"从管道读取,如
youCSVproducingProcess | awk '......'
原创回答
echo "c1,data,c3
c1,data 1,c3
c1,data 2,c3" \
| while IFS=, read col1 col2 col3 ; do
echo "\"$col2\""
done
<强>输出强>
"data"
"data 1"
"data 2"
是基本想法。
您可以使用
创建处理文件的脚本#!/bin/ksh
case $# in 0 ) echo "usage: myScript InputFile" ; exit 1 ;; esac
inFile="$1"
while IFS=, read col1 col2 col3 ; do
echo "\"$col2\""
done < "$inFile"
此处的关键项目是while ... done < "$inFile"
,IFS=,
和read col1 col2 col3
。
与while
(或read var1 var2
)结合时的read line
循环是一次通过文件1行读取的标准解决方案。请注意,这取决于所有在1行上表示的数据标准。包含列内部换行符的多列数据需要采用不同的方法。
(read line
只是一种惯例,它可以是任何有效的变量名称,与col1
或var1
相同; my1Var
也可以使用,而其他许多名称也是如此。< / p>
为了使read line
更有用,read
了解如果列出的变量超过1个(&#39; col1 col2 col3),它将采用std-in(由隐式提供) while
循环),并读取该行数据,将其分解为n
个字段。
read
的默认字段分隔符是space-or-tab-char。 (在这里省略一些细节,你在那里迂腐;-))。使用IFS=,
表示读取该行并按,
字符拆分字段。使用2个逗号,您将获得3个字段,如我的示例数据中所示。
答案 1 :(得分:1)
我认为这可能是一个问题。问题在于您填充数组的方式:
fname=($(sed 1d myfile.csv | cut -d, -f2))
数组的元素是&#34;数据&#34;,&#34;数据&#34;,&#34; 1&#34;,&#34;数据&#34;,&#34; 2& #34; - 你已经失去了&#34;单词&#34;。
Bash有一个很好的mapfile
命令来读取文件或输出命令并将这些行存储到一个数组中。对于ksh你可能需要做
fname=()
sed 1d myfile.csv | while IFS=, read -r col1 col2 rest; do
fname+=( "$col2" )
done
请注意,在for循环中引用数组非常重要(我在对其他问题的回答中确实提到了这一点):
for i in "${fname[@]}"; do
# .......^...........^ ............ quotes here are required
echo "$i"
# ...^..^ ..................... here too
done