извлечение данных из текстовых файлов в csv

Для начала вы можете начать с этого простого цикла bash for:

for i in {001..250} ; do touch ./file$i ; done

Это создаст 250 пустых файлов в текущем каталоге с именами от file001 до file250.

Тач (в данном случае) просто создает файл, если он не существует. Пустой файл. Если вы хотите создать файлы с чем-то внутри, вы можете изменить часть do цикла for. Например, do cp ./master.file ./newfile.$i — файл с именем master.file будет скопирован в 250 новых файлов, которые будут называться newfile.001 до newfile.250.

Это слишком запутанно? Мне потребовалось некоторое время, чтобы понять, как все это работает в bash, но как только мне это удалось, я использую его почти каждый день. Так что не стесняйтесь спрашивать, я постараюсь объяснить это подробнее и/или лучше.

1
18.11.2018, 19:45
3 ответа

Если у вас есть только одна запись для каждого файла, это простой цикл чтения.

#!/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 , чтобы она соответствовала желаемому формату.

{{ 1}}
0
28.01.2020, 01:12

Если есть одна запись на файл и у вас есть GNU awk, вы можете сделать

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

Быстрый и грязный подход, может удовлетворить ваши требования.

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
0
28.01.2020, 01:12

Теги

Похожие вопросы