将文本文件中的数据提取到 csv

将文本文件中的数据提取到 csv

我有一系列格式一致的文本文件,例如:

FirstName: Mary
LastName: Smith
Address: 123 Anywhere St
City: Nowhere
State: TX
Zip: 77777

我需要从这些文件中提取几行并将它们输出到 csv 文件中,格式如下:

<filename>,<FirstName>,<City>,<Zip>

我可以使用简单的 grep 获取我想要的字段,但我不知道如何以我需要的方式获取输出。

答案1

如果每个文件只有一条记录,那么这是一个简单的读取循环。

#!/bin/bash

read_data()
{
  local first last addr city state zip

  file=$1

  while read -r header data
  do
    case $header in
      FirstName:) first=$data ;;
       LastName:) last=$data ;;
        Address:) addr=$data ;;
           City:) city=$data ;;
          State:) state=$data ;;
            Zip:) zip=$data ;;
               *) echo Ignoring bad line $header $data >&2
    esac
  done < $file
  echo "$file,$first,$last,$addr,$city,$state,$zip"
}

for file in *srcfiles*
do
  read_data $file
done

read_data函数读取每一行并将该行分成“标题”和“数据”。一旦到达文件末尾,我们就打印出结果。

我们通过循环为每个源文件调用该函数一次for

注意一些潜在的问题:如果数据中有逗号,那么这会破坏事情,所以你可能想要这样做

  echo "\"$file\",\"$first\",\"$last\",\"$addr\",\"$city\",\"$state\",\"$zip\""

"..."作为将所有内容包含在布局内的输出。如果"数据中有任何内容,那么这也可能导致 CSV 格式错误。

调整echo线条以匹配您想要的格式。

答案2

快速而肮脏的方法,可能适合您的要求。

grep . *|perl -ne 'if(/FirstName: (.*)/){$f=$1}if(/City: (.*)/){$c=$1}if(/^(.*):Zip: (.*)/){print "$1,$f,$c,$2\n"}'

例子:

grep . *
f1.txt:FirstName: Mary
f1.txt:LastName: Smith
f1.txt:Address: 123 Anywhere St
f1.txt:City: Nowhere
f1.txt:State: TX
f1.txt:Zip: 77777
f2.txt:FirstName: Joe
f2.txt:LastName: Bloggs
f2.txt:Address: 444 Anywhere St
f2.txt:City: Nowhere2
f2.txt:State: TXA
f2.txt:Zip: 77737
grep . *|perl -ne 'if(/FirstName: (.*)/){$f=$1}if(/City: (.*)/){$c=$1}if(/^(.*):Zip: (.*)/){print "$1,$f,$c,$2\n"}'
f1.txt,Mary,Nowhere,77777
f2.txt,Joe,Nowhere2,77737

答案3

如果每个文件只有一条记录并且您有 GNU awk,您可以这样做

gawk -F': +' -vOFS=, '
  BEGINFILE{delete rec}
  {rec[$1] = $2}
  ENDFILE{print FILENAME, rec["FirstName"], rec["City"], rec["Zip"]}
' file1.txt file2.txt ...

相关内容