Замена / перестановка столбцов и их значений на основе входных данных с использованием сценариев Unix

#awk

#авк

Вопрос:

Команда,

У меня есть требование изменить / упорядочить столбец CSV-файлов на основе входных данных.

пример :

Файл данных (исходный файл) всегда будет содержать стандартный столбец и его значения пример :

 PRODUCTCODE,SITE,BATCHID,LV1P_DESCRIPTION
MK3,Biberach,15200100_3,Biologics Downstream
MK3,Biberach,15200100_4,Sciona Upstream
MK3,Biberach,15200100_5,Drag envois
MK3,Biberach,15200100_8,flatsylio
MK3,Biberach,15200100_1,bioCovis
 

эти столбцы (PRODUCTCODE, SITE, BATCHID, LV1P_DESCRIPTION) будут стандартными для исходных файлов, и я ищу решение для форматирования этого и создания нового файла со столбцами, которые мы предпочли.

Примечание: Исходный файл / файл данных всегда будет разделяться запятыми

Пример: если я передам PRODUCTCODE, BATCHID в качестве входных данных, то я хотел бы, чтобы только этот столбец и его данные были извлечены из исходного файла и сгенерированы новый файл.

Что-то вроде script_name <output_column> <имя_источника_файла> <имя_файла_целевого объекта>

пример целевого файла :

 PRODUCTCODE,BATCHID
MK3,15200100_3
MK3,15200100_4
MK3,15200100_5
MK3,15200100_8
MK3,15200100_1
 

если я передам output_column как «LV1P_DESCRIPTION, PRODUCTCODE», то выходной файл должен быть таким, как показано ниже

 LV1P_DESCRIPTION,PRODUCTCODE
Biologics Downstream,MK3
Sciona Upstream,MK3
Drag envios,MK3
flatsylio,MK3
bioCovis,MK3
 

Было бы здорово, если бы кто-нибудь мог помочь в этом.

Я пытался использовать некоторые сценарии awk (получил их с какого-то сайта), но это работало не так, как ожидалось, поскольку у меня нет знаний unix, которые затрудняют это изменение.

код awk:

 BEGIN {
    FS = ","
}

NR==1 {
    split(c, ca, ",")
    for (i = 1 ; i <= length(ca) ; i  ) {
        gsub(/ /, "", ca[i])
        cm[ca[i]] = 1
    }
    for (i = 1 ; i <= NF ; i  ) {
        if (cm[$i] == 1) {
            cc[i] = 1
        }
    }
    if (length(cc) == 0) {
        exit 1
    }
}

{
    ci = ""
    for (i = 1 ; i <= NF ; i  ) {
        if (cc[i] == 1) {
            if (ci == "") {
                ci = $i
            } else {
                ci = ci "," $i
            }
        }
    }
    print ci
}
 

приведенный выше код сохраняется как Remove.awk, и он будет вызван другими сценариями, как показано ниже

   var1="BATCHID,LV2P_DESCRIPTION" 
  ## this is  input fields values used for testing
    
    awk -f Remove.awk -v c="${var1}" RESULT.csv > test.csv
 

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

1. Пожалуйста, исправьте свои примеры с помощью ТЕГОВ КОДА для лучшего понимания вашего вопроса, спасибо.

2. я только что отформатировал образцы

3. Что вы искали и что вы нашли? Что вы пробовали, и как это не удалось?

4. во-первых, я не очень хорошо разбираюсь в сценариях UNIX и больше работаю с облачной интеграцией. приведенный ниже код, который я использовал, сохранив его как .awk-файл, но он не работает, когда в моем файле данных больше 4-5 полей.

5. BEGIN { FS = «,» } NR==1 { split(c, ca, «,») для (i = 1 ; i <= длина (ca) ; i ) { gsub(/ /, «», ca[i]) cm[ca[i]] = 1 } для (i = 1 ; i <= NF; i ) { if (cm[$i] == 1) { cc[i] = 1 } } if (длина (cc) == 0) { выход 1 } } { ci = «» для(i = 1 ; i <= NF; i ) {if (cc[i] == 1) { if (ci == «») { ci = $i } else { ci = ci «,» $i } } } распечатать ci }

Ответ №1:

Следующее решение GNU awk должно соответствовать вашим целям:

 awk -F, -v flds="LV1P_DESCRIPTION,PRODUCTCODE" 'BEGIN { split(flds,map,",") } NR==1 { for (i=1;i<=NF;i  ) { map1[$i]=i } } { printf "%s",$map1[map[1]];for(i=2;i<=length(map);i  ) { printf ",%s",$map1[map[i]] } printf "n" }' file
 

Объяснение:

 awk -F, -v flds="LV1P_DESCRIPTION,PRODUCTCODE" '                        # Pass the fields to print as a variable field
   BEGIN { 
           split(flds,map,",")                      # Split fld into an array map using , as the delimiter
         } 
   NR==1 { for (i=1;i<=NF;i  ) { 
              map1[$i]=i                            # Loop through the header and create and array map1 with the column header as the index and the column number the value
           } 
         }
         { printf "%s",$map1[map[1]];                # Print the first field specified (index of map)
           for(i=2;i<=length(map);i  ) { 
             printf ",%s",$map1[map[i]]              # Loop through the other field numbers specified, printing the contents
           } 
           printf "n" 
          }' file
 

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

1. Привет, Раман , спасибо за твой ответ! я протестировал код, и он работает нормально, но на моей стороне есть проблема, я не смогу узнать позицию столбца в моем существующем процессе, скорее я получу имена столбцов, подобные этому var1=»BATCHID,LV2P_DESCRIPTION» . Не уверен , что это то , чем вы можете помочь?. Я также попытаюсь получить позиции в своем процессе, выполнив некоторую логику поиска, чтобы я мог использовать ваш код как таковой.

2. и еще один момент, который я заметил — приведенное выше решение ожидает запятой в конце строки в файле, если обратите внимание, что она переходит к следующей строке LV2P_DESCRIPTION,SITE, BATCHID, dsscs,SITE,batch123,

3. Хорошо, я изменил ответ, чтобы найти номера столбцов и использовать их соответствующим образом. Я не уверен, что вы имеете в виду, говоря «ожидать запятой в конце файла». Я использовал ваши примерные данные, и в конце нет запятых.

4. спасибо Раману за большую помощь, я проверю это через некоторое время и сообщу вам.

5. Привет, Раман. Не уверен, что я здесь делаю что-то не так, посейте, как я не смог правильно получить результаты