Использовать вывод cat или grep как вход в sed

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

У меня есть входной файл (ids.txt), который содержит 8-значные идентификационные номера, 1 на строку. Что-то вроде этого:

11111111 22222222 

Тогда у меня есть файл CSV (users.csv), как это:

 username_prefix user_type expiry_date comments 11111111 SomeTypeHere 31/12/2017 EDT0029448 22222222 SomeTypeHere 31/12/2017 EDT0029448 33333333 SomeTypeHere 31/12/2017 EDT0029448 44444444 SomeTypeHere 31/12/2017 EDT0029448 55555555 SomeTypeHere 31/12/2017 EDT0029448 

Я хочу использовать файл ID в качестве ввода команды sed (или что-то еще), чтобы любые строки в файле CSV, которые соответствуют полю username_prefix идентификатору, перемещаются в новый файл. Таким образом, ожидаемый результат этого процесса будет состоять в том, что исходный файл CSV будет выглядеть так:

 username_prefix user_type expiry_date comments 33333333 SomeTypeHere 31/12/2017 EDT0029448 44444444 SomeTypeHere 31/12/2017 EDT0029448 55555555 SomeTypeHere 31/12/2017 EDT0029448 

И будет новый CSV-файл, содержащий удаленные строки, например:

 username_prefix user_type expiry_date comments 11111111 SomeTypeHere 31/12/2017 EDT0029448 22222222 SomeTypeHere 31/12/2017 EDT0029448 

Я попробовал следующую команду, но сгенерировал выходной файл с 0 байтами.

 cat ids.txt | sed "/$/d" ./adhocUsers_upload_EDT0029448.csv > removed.csv 

BTW, решение не обязательно использовать sed . Казалось, это был подходящий инструмент из того, что я искал.

3 Solutions collect form web for “Использовать вывод cat или grep как вход в sed”

Вот рубиновое решение. Это «бит» дольше, но он также работает, когда идентификаторы находятся в порядке, отличном от файла пользователя. (И это немного более важно, чем sed)

 #!/usr/bin/env ruby ids = [] users = {} header = "" # Read the contents of the user-file into a Hash File.open('users.csv','r') do |users_file| header = users_file.gets users_file.each do |line| id, *content = line.chomp.split(',') users[id] = content end end # For each line in the id-file, add an appropriate line to the removed-file. File.open('ids.txt','r') do |ids_file| File.open('removed.csv', 'a') do |removed_file| removed_file.puts header ids_file.each do |line| id = line.chomp if users[id] removed_file.puts "#{id},#{users[id].join(',')}" users.delete id end end end end # Finally fill the original file with what's left File.open('original.csv', 'a') do |original_file| original_file.puts header users.each_pair do |id, line| original_file.puts "#{id},#{line.join(',')}" end end 

Ваш вывод будет в файлах «original.csv» и «deleted.csv». Если это не то место, где вы предполагали это, просто перемещайте файлы вокруг;)

Звук довольно прост для команды awk :

 awk -F, 'NR==FNR{IDs[$0]++;next} { print >(($1 in IDs)?"removed.csv":"Updated.csv")} ' IDs.txt Users.csv 

Попробуйте этот скрипт, он сохранит совпадающие строки в removed.csv и все остальное будет отправлено на stdout. Обратите внимание, что username_prefix user_type expiry_date comments не будет отправлена ​​в файл removed.csv , поэтому вы должны добавить ее вручную.

 #!/usr/bin/env bash id_file=${1} csv_file=${2} removed_file=${3} while read -r user; do matched='' while read -r id; do if <<< "${user}" grep -F -e "${id}" > '/dev/null'; then matched='yes' break else matched='no' fi done < "${id_file}" [[ "${matched}" == 'yes' ]] && echo "${user}" >> "${removed_file}" [[ "${matched}" == 'no' ]] && echo "${user}" done < "${csv_file}" 

Пример:

 $ myscript.sh ids.txt users.csv removed.csv username_prefix user_type expiry_date comments 33333333 SomeTypeHere 31/12/2017 EDT0029448 44444444 SomeTypeHere 31/12/2017 EDT0029448 55555555 SomeTypeHere 31/12/2017 EDT0029448 $ cat removed.csv 11111111 SomeTypeHere 31/12/2017 EDT0029448 22222222 SomeTypeHere 31/12/2017 EDT0029448 
  • Извлечь определенный раздел
  • Замените имена строк набором новых имен, не нарушая остальную часть файла
  • Как проверить, имеет ли файл разделитель табуляции и имеет 8 столбцов?
  • stream edit> GDRLR5L04EQY8D 3931 | 1166 в> 3931
  • Сравнение значения и удаление строк файла
  • преобразовать строку в столбец на основе определенного ключа
  • Удалить обратную косую черту + последовательности новой строки
  • Другой способ замены новых строк вместо использования tr
  • Эффективно экономить пару каждой строки с линиями другого файла
  • вытягивать линии, которые содержат 1 в 3-й колонке
  • Заверните линии до указанного количества полей
  • Linux и Unix - лучшая ОС в мире.