【问题标题】:Use "cut" in shell script without space as delimiter在没有空格的 shell 脚本中使用“cut”作为分隔符
【发布时间】:2012-04-18 10:27:17
【问题描述】:

我正在尝试编写一个脚本来读取下面的文件内容并提取每行第 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

“world, goodbye for now”的其余部分没有写入输出文件,因为看起来“hello”和“world”之间的空格被用作分隔符?

如何获得正确的输出

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

【问题讨论】:

    标签: shell delimiter cut


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:
      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)。 p>

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

      【讨论】:

        【解决方案3】:

        作为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
        

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 2010-10-23
            • 1970-01-01
            • 2011-10-31
            • 2018-02-13
            • 1970-01-01
            • 2016-11-26
            • 2014-05-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多