【问题标题】:Adding delimiters to CSV column向 CSV 列添加分隔符
【发布时间】:2013-06-09 09:29:19
【问题描述】:

我需要帮助编写一个脚本,该脚本将在单列 csv 文件的两个字符之间添加 :。根据我的研究,awk 看起来像是我需要的工具,但我一直在尝试合并两个解决方案,我正在寻求帮助。

我的 csv 列涉及没有分隔符的 MAC 地址

000000000000 111111111111 222222222222

我需要将输出转换为

00:00:00:00:00:00 11:11:11:11:11:11 22:22:22:22:22:22

我在一个 csv 文件中有大约 1500 个我想转换。

我找到了为每两个字符添加: 的解决方案:

add=000000000000
echo $add | awk '{for(i=1;i<=length($0);i+=2){printf("%s:",substr($0,i,2))}}'|awk '{sub(/:$/,"")};1' 
00:00:00:00:00:00

我还发现了一个将从第 1 列读取的示例:

awk -F "\"*,\"*" '{print $1}' myfile.csv

但是,我需要帮助阅读列中的每一行,应用脚本添加 :,然后将文件写入第 2 列或一个全新的文件,这对我来说并不重要。

【问题讨论】:

  • 另外一点:尽管到目前为止发布的解决方案适用于测试用例,但实际的 MAC 地址是十六进制的,因此示例显示 [0-9](在 sed、awk 或 perl 中)的任何地方都需要成为[0-9a-fA-F]

标签: macos csv awk


【解决方案1】:

GNU sed

sed  -e 's/\([0-9][0-9]\)/\1:/g' -e 's/:$//' file

输入:

000000000000
111111111111
222222222222

输出:

00:00:00:00:00:00
11:11:11:11:11:11
22:22:22:22:22:22

【讨论】:

  • 我使用的是 MAC OSX,但无法正常工作,我一直收到错误消息
  • 我试过 sed ':k;s/([0-9][0-9])([0-9][0-9])/\1:\2/;tk ' input.csv > output.csv 这似乎是复制而没有更改。请记住,所有字段后面都有一个 。中间没有空格。
  • Endoro- 我试了一下,似乎文件被粘贴而没有更改。这是我的命令 - sed 's/([0-9][0-9])\B/\1:/g' in.csv > out.csv
  • 嗨,我试过了,但似乎这在我的文件中用 : 替换了第 4 个“B”。
  • @svt1998gt (et. al) 这在 mac sed 上不起作用的原因是它无法将 ; 识别为命令分隔符。您需要有一个文字换行符或两个 -e 语句
【解决方案2】:

POSIX awk:

{
  for (x = 1; x < length; x += 2) {
    printf "%s%s", substr($0, x, 2), x == length - 1 ? RS : ":"
  }
}

【讨论】:

    【解决方案3】:

    你可以试试

    awk '{print gensub("([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9‌​])","\\1:\\2:\\3:\\4:\\5","g")}' INPUTFILE
    

    【讨论】:

    • @Kevin 是正确的,我认为。如果您使用 gawk,则解决方案可能是 awk '{gensub("([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])","\\1:\\2:\\3:\\4:\\5","g");print}' INPUTFILE,因为 gensub() 具有编号匹配替换,而 gsub() 没有。见gawk manual
    • @Simon 你是对的,谢谢你的纠正!还有凯文,你的答案几乎可以,除了gensub没有替换到位,所以你需要printgensub的返回值。
    【解决方案4】:

    Perl 也将执行并更改 awk 不执行的文件:

    perl -pi -e 's/(..)/$1:/g;s/:$//g' your_file
    

    测试:

    > cat temp
    000000000000
    111111111111
    222222222222
    > perl -pe 's/(..)/$1:/g;s/:$//g' temp
    00:00:00:00:00:00
    11:11:11:11:11:11
    22:22:22:22:22:22
    >
    

    如果你坚持 awk :

    awk '{gsub("..","&:");print substr($0,0,length($0)-1)}' your_file
    

    【讨论】:

    • 我尝试使用 perl,输出在最后一个 0 的末尾放了一个 :,这是输出示例 - 00:00:00:00:00:00: 1:11 :11:11:11:11:1 :
    • 您的值似乎在行尾有空格。请提供您正在处理的正确输入。您的文件看起来如何?
    • 我很抱歉 Vijay,最初的问题已更新。没有空格,只有一个换行符。
    • 我测试了相同的输入并且它对我有用,正如您在我的回答中看到的那样。你得到什么输出?
    • 我能够再次编辑 csv 文件,并且 perl 语句在每一行的末尾发布一个 :。
    【解决方案5】:

    sed 的另一种方式:

    sed 's/../:&/2g' file
    

    $ cat file
    000000000000
    111111111111
    222222222222
    $ sed 's/../:&/2g' file
    00:00:00:00:00:00
    11:11:11:11:11:11
    22:22:22:22:22:22
    

    【讨论】:

      猜你喜欢
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多