У меня есть набор данных csv student.csv с 1000 строк и 10 столбцов.

Данные примера выглядят так:

s_id,s_name,s_dob,s_class,s_marks,s_parentname,
   1,abc,1/1/18,5,49,def,
   2,xyz,1/1/17,4,85,abc,
   3,pqr,1/2/18,2,78,mnp,

Из этого набора данных я хочу скопировать все даты, в строках которых есть «abc», в текстовый файл.

Ожидаемый результат:

text.txt
1/1/18
1/1/17
0
Jeff Schaller 28 Сен 2019 в 14:07
Если abcd существует в строке, удовлетворяет ли это вашим критериям abc exists или нет? Другими словами, вы ищете полные совпадения на поле или частичные совпадения?
 – 
Ed Morton
28 Сен 2019 в 20:32
Нет, не устраивает. Поиск полных совпадений, а не частичных совпадений. Тэнка @EdMorton.
 – 
ramu suri
29 Сен 2019 в 05:24
Пожалуйста. Хорошо, я добавил ответ, учитывая это.
 – 
Ed Morton
29 Сен 2019 в 17:21

3 ответа

Лучший ответ
grep abc student.csv | cut -d, -f 3 >text.txt

Это сначала извлечет каждую строку из student.csv, содержащую подстроку abc в любом месте, а затем вырежет третий столбец с разделителями-запятыми из этих строк и сохранит их в text.txt.

С данными, указанными в вопросе, text.txt в конечном итоге будет содержать

1/1/18
1/1/17

Это зависит от того, что исходный файл представляет собой простой CSV-файл, то есть без полей, содержащих встроенные запятые или символы новой строки.

Если вы хотите искать abc как полное слово, используйте grep -w abc вместо простого grep abc. Это позволит избежать сопоставления строк, содержащих такие строки, как abcde, но по-прежнему будет соответствовать полю, содержащему abc xyz.

Если вы ищете поля, содержащие произвольную сложную строку (все еще в простом CSV-файле), и если вам нужно, чтобы поле было точно равно этой строке, вам придется перебирать поля в каждой строке:

string='some string' awk -F, '{ for (i = 1; i <= NF; ++i) if ($i == ENVIRON["string"]) { print $3 ; next } }' student.csv

Этот код awk перебирает все поля в каждой строке в поисках поля с разделителями-запятыми, значение которого точно совпадает со значением переменной среды string. Как только такое поле найдено, печатается 3-е поле.

1
Kusalananda 28 Сен 2019 в 10:27
Привет, @Kusalananda, спасибо за ответ. Оно работает. Большое спасибо за усилия.
 – 
ramu suri
29 Сен 2019 в 05:40
Могу ли я получить какое-либо предложение о том, как скопировать столбец s_marks, в строке которого есть abc и значение s_marks выше 15, в текстовый файл вместе с заголовками. Обратите внимание, что значения s_marks должны быть отсортированы и напечатаны в текстовом файле. Заранее спасибо @Kusalananda
 – 
ramu suri
29 Сен 2019 в 09:08

Используя Miller (https://github.com/johnkerl/miller), начиная с

s_id,s_name,s_dob,s_class,s_marks,s_parentname,
1,abc,1/1/18,5,49,def,
2,xyz,1/1/17,4,85,abc,
3,pqr,1/2/18,2,78,mnp,

И бег

mlr --nidx --fs "," filter -S '$2=="abc"' then cut -f 3 input.txt >output.txt

У тебя будет

1/1/18
1
aborruso 28 Сен 2019 в 09:57

Учитывая, что вам нужны полные совпадения полей:

$ awk -F, 'FNR==1{print FILENAME} /(^|,)abc(,|$)/{print $3}' file
file
1/1/18
1/1/17

Или если abc может фактически содержать метасимволы RE, которые вы хотите обрабатывать буквально, и поэтому вам нужно выполнить строку, а не соответствие регулярному выражению:

$ awk -F, 'FNR==1{print FILENAME} index(","$0",",",abc,"){print $3}' file
file
1/1/18
1/1/17

Или распечатать заголовок столбца:

$ awk -F, 'FNR==1{print $3} /(^|,)abc(,|$)/{print $3}' file
s_dob
1/1/18
1/1/17

$ awk -F, 'FNR==1{print $3} index(","$0",",",abc,"){print $3}' file
s_dob
1/1/18
1/1/17
0
Ed Morton 29 Сен 2019 в 18:18
Как я могу скопировать заголовок, т.е. s_dob, в выходной файл. Заранее спасибо.
 – 
ramu suri
29 Сен 2019 в 18:15
Я обновил свой ответ. Вы должны показать это как часть ожидаемого результата в вашем вопросе.
 – 
Ed Morton
29 Сен 2019 в 18:20