Как перебирать текстовый файл с файлом csv

#awk #grep

#awk #grep

Вопрос:

У меня есть 2 файла, первый:

values.txt

 test@gmail.com
test1@gmail.com
test3@gmail.com
test4@gmail.com
test5@gmail.com
test6@gmail.com
test7@gmail.com
test8@gmail.com
test9@gmail.com
test10@gmail.com
 

data.csv

 "username","email"
"user","test@gmail.com"
"user1","test1@gmail.com"
"user2","test3@gmail.com"
"user4","test4@gmail.com"
"user456","loka@gmail.com"
"user789","lopa@gmail.com"
"user5","test7@gmail.com"
"user","xpos@gmail.com"
"user5","test9@gmail.com"
"user","xpx@gmail.com"
 

Я хочу, чтобы результат был таким:

 "user","test@gmail.com"
"user1","test1@gmail.com"
"user2","test3@gmail.com"
"user4","test4@gmail.com"
"user5","test7@gmail.com"
"user5","test9@gmail.com"
 

Что я смог сделать :

 awk -F',' '$2 ~ /test9@gmail.com/ {print $0}' data.csv > test1.csv
 

Это создаст новый файл test1.csv, содержащий:

 "user5","test9@gmail.com"
 

Не удалось выяснить, как перебирать файл и обмениваться строкой test9@gmail.com с values.txt

Комментарии:

1. Перекрестная публикация в Unix и Linux ( unix.stackexchange.com/q/632313 ) и AskUbuntu ( askubuntu.com/q/1313072 ).

Ответ №1:

 $ awk -F, -v q='"' 'NR==FNR{a[q $0 q]; next} 
                    FNR==1 || $2 in a' values data

"username","email"
"user","test@gmail.com"
"user1","test1@gmail.com"
"user2","test3@gmail.com"
"user4","test4@gmail.com"
"user5","test7@gmail.com"
"user5","test9@gmail.com"
 

для печати без заголовка просто удалите FNR==1 ||

Комментарии:

1. Спасибо за ответ, к сожалению, при попытке ничего не происходит, возможно ли сохранить его в новом файле csv?

2. просто перенаправьте вывод с помощью > outputfile

3. К сожалению, пустой файл. Я буду работать над этим, спасибо

4. убедитесь, что вы записали имя файла так, как вы его назвали, с суффиксами. Я использовал имена-заполнители.

5. Я сделал это, возвращая мне только заголовок

Ответ №2:

На основе ваших данных grep также должно работать следующее:

 grep -Fwf values.txt data.csv

"user","test@gmail.com"
"user1","test1@gmail.com"
"user2","test3@gmail.com"
"user4","test4@gmail.com"
"user5","test7@gmail.com"
"user5","test9@gmail.com"
 

Комментарии:

1. Спасибо за ваш ответ, поэтому я попробовал, и, к сожалению, я получаю весь исходный файл без сортировки.

2. Скорее всего, у вас есть разрывы строк DOS в вашем файле. Запустите dos2unix перед запуском этого grep

Ответ №3:

если вы не можете предположить, что файлы были отсортированы вообще, попробуйте

     gawk -b -e 'BEGIN { 
   
        CONST_DBLQUOTE = sprintf("%c", 34)       # safe double quote, 
                                                 # maybe too cautious

        FILENAME = ARGV[ ARGC – 2 ]              # always the item
                                                 # prior to last in
                                                 # arguments in 0-based 
                                                 # index, by design

        FS = "^$";                               # don't waste time                                                                                                                                 
                                                 # trying to split fields
        while (getline) { valuesL[$0]   } 
        nextfile
        
        FS = CONST_DBLQUOTE
        PROCINFO["sorted_in"] = "@val_num_asc"   # perform auto-sorting

    } (NF==1) || ($(NF-1) in valuesL) {

        inputL[NR] = $0 

    } END { for (line in inputL) { print line } }' values.txt data.csv
 

Я думаю, что это должно справиться с этим просто отлично, в Юникоде или нет. Если вы знаете, что файл предварительно отсортирован, и у вас ОЧЕНЬ большой набор входных данных для работы, вместо этого запустите его с помощью mawk1.9.9.6 .