Use saída de cat ou grep como entrada para sed

0

Procurei mensagens semelhantes neste site, mas não consegui fazê-las funcionar para o meu problema.

Eu tenho um arquivo de entrada (ids.txt) que contém números de identificação de 8 dígitos, 1 por linha. Algo parecido com isto:

11111111
22222222

Então eu tenho um arquivo CSV (users.csv) assim:

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

Eu quero usar o arquivo IDs como entrada para um comando sed (ou algo assim) para que quaisquer linhas no arquivo CSV que correspondam ao campo username_prefix para um ID sejam movidas para um novo arquivo. Portanto, a saída esperada desse processo seria que o arquivo CSV original ficaria assim:

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

E haverá um novo arquivo CSV que contém as linhas removidas, como:

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

Eu tentei o seguinte comando, mas ele gerou um arquivo de saída de 0 byte.

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

BTW, a solução não precisa usar sed . Apenas parecia ser a ferramenta apropriada do que eu pesquisei.

    
por nedlud 04.08.2017 / 04:08

3 respostas

1

Aqui está uma solução de rubi. É um "bit" mais longo, mas também funciona quando os IDs estão em uma ordem diferente do arquivo de usuários. (E é um pouco mais sustentável do que o 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

Sua saída estará nos arquivos "original.csv" e "removed.csv". Se não é onde você imaginou, apenas mova os arquivos;)

    
por 04.08.2017 / 06:45
2

O som é muito fácil para o comando awk :

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

Tente com este script, ele salvará as linhas correspondentes em removed.csv e tudo o mais será enviado para a stdout. Note que a linha username_prefix user_type expiry_date comments não será enviada para o arquivo removed.csv , então você deve adicioná-la manualmente.

#!/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}"

Exemplo:

$ 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
    
por 04.08.2017 / 07:43