将两个单词串作为单个字符串读取,在终端中使用cut或awk

时间:2015-12-11 12:41:13

标签: ksh

我的问题将来自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

2 个答案:

答案 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只是一种惯例,它可以是任何有效的变量名称,与col1var1相同; 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