Как преобразовать первую букву всех слов из нескольких столбцов CSV-файла в верхний регистр, а остальные буквы - строчные? - PullRequest
1 голос
/ 04 октября 2019

Bash 4.4.0 Ubuntu 16.04

У меня есть несколько столбцов в файле CSV, которые являются заглавными буквами, а некоторые строчными. Некоторые столбцы содержат только одно слово, в то время как другие могут содержать 50 слов. В настоящее время я преобразовываю столбец за столбцом с 2 командами, и это довольно обременительно для сервера, когда файл имеет 50 тыс. Строк.

Пример:

#-- Place the header line in a temp file
head -n 1 "$tmp_input1" > "$tmp_input3"
#-- Remove the header line in orginal file
tail -n +2 "$tmp_input1" > "$tmp_input1-temp" && mv "$tmp_input1-temp" "$tmp_input1"
#-- Change the words in the 11th column to lower case then change the first leter to upper case
awk -F"," 'BEGIN{OFS=","} {$11 = tolower($11); print}' "$tmp_input4" > "$tmp_input5"
sed -i "s/\b\(.\)/\u\1/g" "$tmp_input5"
#-- Change the words in the 12th column to lower case then change the first leter to upper case
awk -F"," 'BEGIN{OFS=","} {$12 = tolower($12); print}' "$tmp_input5" > "$tmp_input6"
sed -i "s/\b\(.\)/\u\1/g" "$tmp_input6"
#-- Change the words in the 13th column to lower case then change the first leter to upper case
awk -F"," 'BEGIN{OFS=","} {$13 = tolower($13); print}' "$tmp_input6" > "$tmp_input7"
sed -i "s/\b\(.\)/\u\1/g" "$tmp_input7"
cat "$tmp_input7" >> "$tmp_input3"

Можно ли сделать несколькостолбцы в одной команде?

Вот пример файла csv:

"dealer_id","vin","conditon","stocknumber","make","model","year","broken","trim","bodystyle","color","interiorcolor","interiorfabric","engine","enginedisplacement","engineaspiration","engineText","transmission","drivetrain","mpgcity","mpghighway","mileage","cylinders","fuelconditon","optiontext","description","titlestatus","warranty","price","specialprice","window_sticker_price","mirrorhangerprice","images","ModelCode","PackageCodes"
"JOHNVANC04A","2C4RC1N73JR290946","N","JR290946","Chrysler","Pacifica","2018","","Hybrid Limited FWD","Mini-van, Passenger","Brilliant BLACK Crystal PEARL Coat","","..LEATHER SEATS..","V6 Cylinder Engine","3.6L","","","AUTOMATIC","FWD","0","0","553","6","H","..1-SPEED A/T..,..AUTO-OFF HEADLIGHTS..,..BACK-UP CAMERA..,..COOLED DRIVER SEAT..,..CRUISE CONTROL..","======KEY FEATURES INCLUDE: . LEATHER SEATS. THIRD ROW SEAT. QUAD BUCKET SEATS. REAR AIR. HEATED DRIVER SEAT.","","0","41680","","48830","","http://i.autoupktech.com/c640/9c40231cbcfa4ef89425d108e4e3a410.jpg",http://i.autoupnktech.com/c640/9c40231cbcfa4ef89425d108e4e3a410.jpg","RUES53","AAX,AT2,DFQ,EH3,GWM,WPU"

Вот фрагмент уточненных выше столбцов

Column 11 should be - "Brilliant Black Crystal Pearl Coat"
Column 13 should be - "Leather Seats"
Column 16 should be - "Automatic"
Column 23 should be - "1-Speed A/T,Auto-Off Headlights,Back-up Camera"
Column 24 should be - "Key Features Include: Leather Seats,Third Row Seat"

Имейте в видудвойные кавычки, окружающие столбцы, не могут быть удалены. Мне нужно конвертировать только определенные столбцы, а не весь файл. Вот пример преобразованных столбцов 11, 13, 16, 23 и 24.

"Brilliant Black Crystal Pearl Coat","Leather Seats","Automatic","1-Speed A/T,Auto-Off Headlights,Back-up Camera","Key Features Include: Leather Seats,Third Row Seat"

Ответы [ 5 ]

2 голосов
/ 04 октября 2019

Просто, чтобы добавить другой вариант, вот один вкладыш, использующий просто sed:

sed -i -e 's/.*/\L&/' -e 's/[a-z]*/\u&/g' filename

И вот подтверждение концепции:

$ cat testfile 
jUSt,a,LONG,list of SOME,RAnDoM WoRDs
ANother LIne
OneMore,LiNe
$ sed -e 's/.*/\L&/' -e 's/[a-z]*/\u&/g' testfile 
Just,A,Long,List Of Some,Random Words
Another Line
Onemore,Line
$ 

Если вы хотите преобразовать только заголовки файла CSV (первая строка), просто замените s на 1s в обоих шаблонах поиска.

Вы можете найти отличную статью, объясняющую магиюздесь: sed - конвертировать в заглавный регистр .

1 голос
/ 05 октября 2019

Вот еще один альтернативный вариант (не по теме, я знаю) в Python 3:

import csv
from pathlib import Path

infile = Path('infile.csv')
outfile = Path('outfile.csv')

titled_cols = [10, 12, 15, 22, 23]
titled_data = []

with infile.open() as fin, outfile.open('w', newline='') as fout:
    for row in csv.reader(fin, quoting=csv.QUOTE_ALL):
        for i,col in enumerate(row):
            if i in titled_cols:
                col = col.title()
        titled_data.append(row)    
    csv.writer(fout, quoting=csv.QUOTE_ALL).writerows(titled_data)

Просто определите столбцы, для которых вы хотите, чтобы заголовок включался в titled_cols (столбцы имеют нулевые индексы)и он будет делать то, что вы хотите.

Я думаю, infile и outfile говорят сами за себя, а outfile будет содержать измененную версию вашего исходного файла.

Я надеюсь, что этопомогает.

1 голос
/ 04 октября 2019

Эта версия использует AWK для выполнения работы:

Это команда (измените file на ваше имя файла)

awk  -F"," 'BEGIN{OFS=","}{ for (i=1; i<=NF; i++) { $i=toupper(substr($i,1,1))""tolower(substr($i,2,length($i)))}print $0}' file | awk -F" "  'BEGIN{OFS=" "} { for (i=1; i<=NF; i++) { $i=toupper(substr($i,1,1))""substr($i,2,length($i))}print $0}'

Тест:

cat file
pepe is cool,ASDASD ASDAS,and no podpoiaops
awk  -F"," 'BEGIN{OFS=","}{ for (i=1; i<=NF; i++) { $i=toupper(substr($i,1,1))""tolower(substr($i,2,length($i)))}print $0}' file | awk -F" "  'BEGIN{OFS=" "} { for (i=1; i<=NF; i++) { $i=toupper(substr($i,1,1))""substr($i,2,length($i))}print $0}'
Pepe Is Cool,Asdasd Asdas,And No Podpoiaops

Пояснение

  • BEGIN{OFS=","} сообщает awk, как обойти строку.
  • В операторе for используется NF, встроенная внутренняя переменная для числа полей в каждой строке
  • Substr разделяет и изменяет первую букву поля и присваивается егоснова значение строки
  • Печатается вся строка print $0
  • Наконец, вторая awk делит строки, созданные в первом примере, но на этот раз с пробелами в качестве разделителя. Таким образом, он обнаруживает все разные слова в файле и меняет каждый первый символ из них.

Надеюсь, это поможет

1 голос
/ 04 октября 2019

Предполагая, что поля файла CSV не заключены в двойные кавычки, это означает, что мы можем просто разбить запись на запятые и пробелы, как насчет Perl решения:

perl -pe 's/(^|(?<=[,\s]))([^,\s])([^,\s]*)((?=[,\s])|$)/\U$2\L$3/g' input.csv

input.csv:

Bash,4.4.0,Ubuntu,16.04
I have several columns in a CSV file,that, are, all capital letters
and  some are lowercase.
Some columns have only,one,word,while others may have 50 words.

вывод:

Bash,4.4.0,Ubuntu,16.04
I Have Several Columns In A Csv File,That, Are, All Capital Letters
And  Some Are Lowercase.
Some Columns Have Only,One,Word,While Others May Have 50 Words.
1 голос
/ 04 октября 2019

Вы можете создать пользовательскую функцию и применить ее к столбцам, которые нужно изменить.

awk -F, 'function toproper(s) { return toupper(substr(s, 1, 1)) tolower(substr(s, 2, length(s))) } {printf("%s,%s,%s,%s\n", toproper($1), toproper($2), toproper($3), toproper($4));}'

Ввод:

FOO,BAR,BAZ,ETC

Вывод:

Foo,Bar,Baz,Etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...