使用awk将csv文件读入csh

时间:2015-05-14 10:05:13

标签: csv awk csh

假设我有一个逗号分隔的文件,名为' list.txt'其中包含以下内容:

1,fileA
2,fileB

我想在我的csh脚本中将这些内容读入while循环,以便我可以分别操作逗号分隔的字段。我需要在输入文本文件中为任意数量的行扩展它,而不是在此示例中为2。

    #!/bin/csh
    set j=1
    while ($j <= 2)
      set index = "`awk -F"," '{if (NR==$j) print $1}' list.txt`"
      set file = "`awk -F"," '{if (NR==$j) print $2}' list.txt`"
      echo $index
      echo $file
      @ j++
    end

所以我希望这个输出是

 1
 fileA
 2
 fileB

但我得到了:

1,fileA
1,fileA
2,fileB
2,fileB

我在这里缺少什么?如果我在我的csh脚本之外的终端中为任何给定的行运行等效的awk命令,它就像我期望的那样工作。

awk -F"," '{if (NR==1) print $1}' list.txt

返回

1

我相信csh脚本的问题在于使用指定分隔符的双引号逗号,这意味着csh中的其他内容,但我无法找出解决方案。

4 个答案:

答案 0 :(得分:1)

不确定你的目标是什么,但你可以这样做:

tr ',' '\n' <file
1
fileA
2
fileB

答案 1 :(得分:1)

如果您的兴趣是var enumToLookup = new EnumToLookup(); enumToLookup.Apply(context);

,请尝试
awk

答案 2 :(得分:0)

到目前为止,如何使用任何支持数组的awk和shell来告诉我们这些内容,例如:击:

$ awk -F, -v OFS='\n' '{$1=$1}1' file
1
fileA
2
fileB

$ IFS=$'\n' arr=( $(awk -F, -v OFS='\n' '{$1=$1}1' file) )

$ echo "${arr[0]}"
1
$ echo "${arr[1]}"
fileA
$ echo "${arr[2]}"
2
$ echo "${arr[3]}"
fileB

现在,如果您告诉我们您想要使用awk输出做什么,我们可以提供指导。

要明确的是,上面的回声不是任何建议解决方案的一部分,它们只是为了显示一个数组被填充。如果您愿意,这里的循环相同(我在回声中添加了一些周围的< >个字符,只是为了清楚回声是什么与awk相比):

$ cat tst.sh
IFS=$'\n' arr=( $(awk -F, -v OFS='\n' '{$1=$1}1' file) )
for i in "${arr[@]}"
do
    echo "< $i >"
done

$ ./tst.sh
< 1 >
< fileA >
< 2 >
< fileB >

但不清楚这些是否有用。这更像是你想要的东西:

$ awk -F, -v OFS='\n' '{$1=$1}1' file | xargs -I {} -n1 echo "<" {} ">"
< 1 >
< fileA >
< 2 >
< fileB >

同样,在您向我们展示您想要对输入文件的内容做什么之前,我们无法帮助您弄清楚如何实施解决方案。

考虑到你在评论中所说的关于想要运行一个名为gausmooth的命令,其中args包含从输入文件生成的文件名,这里有一种方法(删除回显到执行命令而不是只打印它:)

$ cat tst.sh
awk -F, '{print $2$1}' file |
xargs -I {} echo gausmooth in="/home/Documents/{}" out="/home/Documents/gs_{}"

$ ./tst.sh
gausmooth in=/home/Documents/fileA1 out=/home/Documents/gs_fileA1
gausmooth in=/home/Documents/fileB2 out=/home/Documents/gs_fileB2

再次 - 如果那不是你想要的,请告诉我们故事的其余部分。

鉴于您的新要求,这可能是您想要的:

$ cat file
fileA1,fileA2
fileB1,fileB2
$
$ while IFS=, read -r in1 in2
do
    echo gausmooth in1="/home/Documents/$in1" in2="/home/Documents/$in2" out="/home/Documents/gs_${in1%%[0-9]*}"
done < file
gausmooth in1=/home/Documents/fileA1 in2=/home/Documents/fileA2 out=/home/Documents/gs_fileA
gausmooth in1=/home/Documents/fileB1 in2=/home/Documents/fileB2 out=/home/Documents/gs_fileB

正如我在另一条评论中提到的,通常的建议是避免一般的shell循环,但是当我控制输入时,我有时会使用它们来简单/清晰,并且它很容易受到限制,因此我就是#&# 39;在这种情况下完成了。假设您的文件名都不包含逗号或换行符,并且可以通过从第一个out文件中删除尾随数字来创建in文件的名称。

答案 3 :(得分:-1)

在这种情况下,解决方案是使用cut代替awk

#!/bin/csh
foreach LINE ( `cat list.txt` )
  set index = `echo "$LINE" | cut -d',' -f 1`
  set file  = `echo "$LINE" | cut -d',' -f 2`
  echo $index
  echo $file
end

产生所需的输出

1
fileA
2
fileB

并将字符串存储在变量中以供进一步使用。