Отфильтруйте файл .CSV на основе значений 5-го столбца файла и распечатайте эти записи в новый файл.

16

У меня есть файл .CSV в следующем формате:

"column 1","column 2","column 3","column 4","column 5","column 6","column 7","column 8","column 9","column 10
"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23455","12312255564","string, with, multiple, commas","string with or, without commas","string 2","USD","433","70%","07/15/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""
"46476","15467534544","lengthy string, with commas, multiple: colans","string with or, without commas","string 2","CAND","388","70%","09/21/2013",""

5-й столбец файла имеет разные строки. Мне нужно отфильтровать файл на основе значения 5-го столбца. Допустим, мне нужен новый файл из текущего файла, в котором есть записи только со значением «строка 1» в его пятом поле.

Для этого я попробовал следующую команду,

awk -F"," ' { if toupper($5) == "STRING 1") PRINT }' file1.csv > file2.csv

но он выдавал мне ошибку следующим образом:

awk: { if toupper($5) == "STRING 1") PRINT }
awk: ^ syntax error
awk: { if toupper($5) == "STRING 1") PRINT }
awk: ^ syntax error

Затем я использовал следующее, что дает мне странный вывод.

awk -F"," '$5="string 1" {print}' file1.csv > file2.csv

Выход:

"column 1" "column 2" "column 3" "column 4" string 1 "column 6" "column 7" "column 8" "column 9" "column 10
"12310" "42324564756" "a simple string with a comma" string 1 without commas" "string 1" "USD" "12" "70%" "08/01/2013" ""
"23455" "12312255564" "string with string 1 commas" "string with or without commas" "string 2" "USD" "433" "70%" "07/15/2013" ""
"23525" "74535243123" "string with commas string 1 "string with or without commas" "string 1" "CAND" "744" "70%" "05/06/2013" ""
"46476" "15467534544" "lengthy string with commas string 1 "string with or without commas" "string 2" "CAND" "388" "70%" "09/21/2013" ""

PS: я использовал команду toupper, чтобы быть в безопасности, так как я не уверен, будет ли строка в нижнем или верхнем регистре. Мне нужно знать, что не так с моим кодом и имеет ли значение место в строке при поиске шаблона с помощью AWK.

Dhruuv
источник

Ответы:

17
awk -F '","'  'BEGIN {OFS=","} { if (toupper($5) == "STRING 1")  print }' file1.csv > file2.csv 

Выход

"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""

Я думаю, что это то, что вы хотите.

limovala
источник
На выходе получается именно то, что мне было нужно. Я не думал о создании в '","'качестве разделителя, иначе это решило бы мою проблему ... отличное решение ...
Дхруув
@Dhruuv создание '","'разделителя - это то, что предлагает большинство ответов на ваш предыдущий вопрос :).
Terdon
@terdon: да, я знаю, но это не пришло мне в голову, когда у меня возникла проблема. Честно говоря, я подумал, что это может быть что-то с командой или что-то другое, кроме разделителей, которые вызывали проблему ... :) Следовательно, не дать ему попробовать ... :(
Dhruuv
2
@Dhruuv не уверен в деталях, так как я не могу сказать, что ты пытаешься сделать, но твое другое условие почти наверняка неверно. Вы пытаетесь напечатать только если $ 5 - это HYPERION? Если так, попробуйте else{if(toupper($5)=="HYPERION"){print}}. В данный момент не на моем компьютере, поэтому у меня может быть неправильный синтаксис, но вы не можете указать условие для оператора else.
Тердон
1
awk -F '","' 'BEGIN {OFS=","} { if (NR==1) {print} else{if (toupper($5) == "STRING 1") print} }' file1
лимовала
2

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

$ perl -mText::CSV_XS -WlanE '
    BEGIN {our $csv = Text::CSV_XS->new;} 
    $csv->parse($_); 
    my @fields = $csv->fields(); 
    print if $fields[4] =~ /string 1/i;
' file1.csv
"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""

источник
-1
awk 'BEGIN {FS = "," }'  '{ (if toupper($5)  == "STRING 1") print; }'  file1.csv > file2.csv
Персидский залив
источник
Извините, но ваше решение не возвращает никаких записей из файла ... Я думаю, что просто добавив разделитель, как это '","'будет ... спасибо ... :)
Dhruuv
@Mohsen -1, потому что 1) вам нужно экранировать "или они не понимаются как части разделителя файлов. См. Ответы на другой вопрос OP и 2) вы отделяете блок BEGIN от остальной части команды, которая полностью сломайте его. Попробуйте awk 'BEGIN {FS = "," }' '{print $0}', вы увидите, что он не производит вывод. В будущем, пожалуйста, проверьте свои ответы, чтобы увидеть, действительно ли они работают, прежде чем публиковать их
Terdon