在shell脚本中使用“cut”而不用空格作为分隔符

时间:2012-04-18 10:27:17

标签: shell delimiter cut

我正在尝试编写一个脚本来读取下面的文件内容,然后在每行的第6列中提取值,然后在没有第6列的情况下打印每一行。逗号用作分隔符。

输入:

123,456,789,101,145,5671,hello world,goodbye for now
223,456,789,101,145,5672,hello world,goodbye for now
323,456,789,101,145,5673,hello world,goodbye for now

我做的是

#!/bin/bash
for i in `cat test_input.txt`
do
    COLUMN=`echo $i | cut -f6 -d','`
    echo $i | cut -f1-5,7- -d',' >> test_$COLUMN.txt
done

我得到的输出是

test_5671.txt:

123,456,789,101,145,hello

test_5672.txt:

223,456,789,101,145,hello

test_5673.txt:

323,456,789,101,145,hello

其余的“世界,现在再见”没有写入输出文件,因为看起来“hello”和“world”之间的空格被用作分隔符?

如何获得正确的输出

123,456,789,101,145,hello world,goodbye for now

4 个答案:

答案 0 :(得分:2)

cut 命令不是问题,但是你正在使用 for 循环。对于第一个循环运行,变量 i 将仅包含123,456,789,101,145,5671,hello

如果你坚持逐行读取输入文件(效率不高),你最好使用这样的读取循环:

while read i
 do
  ...
 done < test_input.txt

答案 1 :(得分:1)

echo '123,456,789,101,145,5671,hello world,goodbye for now' | while IFS=, read -r one two three four five six seven eight rest
do
    echo "$six"
    echo "$one,$two,$three,$four,$five,$seven,$eight${rest:+,$rest}"
done

打印:

5671
123,456,789,101,145,hello world,goodbye for now

请参阅man bash Parameter Expansion部分了解:+语法(基本上它会输出一个逗号,$rest如果定义了$rest 和< / em>非空)。

另外,you shouldn't use for to loop over file contents

答案 2 :(得分:1)

作为ktf mentioned,您的问题不在于cut,而在于您将这些行传递到cut的方式。他/她提供的解决方案应该有效。

或者,您可以使用awk行:

来实现相同的行为
awk -F, '{for(i=1;i<=NF;i++) {if(i!=6) printf "%s%s",$i,(i==NF)?"\n":"," > "test_"$6".txt"}}' test_input.txt

为清楚起见,这是一个冗长的版本:

awk -F, '  # "-F,": using comma as field separator
{ # for each line in file

  for(i=1;i<=NF;i++) {  # for each column

    sep = (i == NF) ? "\n" : ","  # column separator
    outfile = "test_"$6".txt"     # output file

    if (i != 6) {  # skip sixth column
      printf "%s%s", $i, sep > outfile
    }

  }

}' test_input.txt

答案 3 :(得分:0)

一个简单的方法ID,使用 tr 命令将espace carracter转换为#并在执行cat commande后将其重新转换为espace。