Массовое преобразование чисел в текстовых файлах с помощью sed

В настоящее время у меня есть несколько файлов с миллионами строк, которые похожи на следующее:

565 0 10 12 23 18 17 25
564 1 7 12 13 16 18 40 29 15

Номера 565 и 564 являются идентификаторами, и я извлек все уникальные идентификаторы из различных файлов и связал их в единственный файл, будучи похож на следующее:

565
564
182
982

Затем, я хочу провести следующее преобразование чисел в исходных файлах:

565 -> 1
564 -> 2
182 -> 3
982 -> 4

так, чтобы исходные файлы были похожи:

1 0 10 12 23 18 17 25
2 1 7 12 13 16 18 40 29 15

Я знаю, как применить однократное преобразование с помощью sed, но являюсь там какими-либо способами указать способ преобразования в текстовом файле и использовать сценарий оболочки для применения его к исходным файлам?

Спасибо.

1
задан 6 June 2017 в 13:43

2 ответа

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

awk '{$1=NR} 1' file.txt

Это восстановит целую запись с пространством как новый разделитель полей, но в этом случае я думаю, что мы в безопасности, поскольку поля разделяются пробелами.


Теперь, вот способы решить Вашу проблему, где у Вас есть дополнительный файл скажем, id.txt с первыми полями:

Вы были бы более обеспеченным использованием чего-то, что может понять номер строки и отслеживать их, например. awk:

awk 'NR==FNR {a[$0]=NR; next} {$1=a[$1]} 1' id.txt file.txt
  • принятие, id.txt содержит извлеченные первые столбцы только и file.txt основной файл

  • NR==FNR {a[$0]=NR; next} сохраняет каждую запись файла id.txt как ключ ассоциативного массива a причем значение является соответствующим номером строки. next гарантирует, что никакая последующая обработка не сделана к записям id.txt

  • {$1=a[$1]} устанавливает первое поле на значение соответствующего элемента массива; обратите внимание, что, это имеет протест восстановления целой записи с пространством как разделитель, но я предполагаю в этом случае, что мы в безопасности усилить эту краткость. 1 просто заполнитель для интерпретации true так, чтобы целая запись была распечатана впоследствии


Если Вы чувствуете себя необычными, можно использовать некоторый стандарт *, отклоняют инструменты, со справкой от замены процесса (<()) из bash и paste наконец:

paste -d' ' <(nl id.txt | cut -f1) <(cut -d' ' -f2- file.txt) 
  • nl id.txt | cut -f1 получает номер строки

  • cut -d' ' -f2- file.txt получает все поля, но первое


Пример:

% cat file.txt                                               
565 0 10 12 23 18 17 25
564 1 7 12 13 16 18 40 29 15
182 10 12 23 18 17 25
892 1 7 12 13 16 18 40 29 15

% awk '{$1=NR} 1' file.txt
1 0 10 12 23 18 17 25
2 1 7 12 13 16 18 40 29 15
3 10 12 23 18 17 25
4 1 7 12 13 16 18 40 29 15

% cat id.txt                                                 
565
564
182
892

% awk 'NR==FNR {a[$0]=NR; next} {$1=a[$1]} 1' id.txt file.txt
1 0 10 12 23 18 17 25
2 1 7 12 13 16 18 40 29 15
3 10 12 23 18 17 25
4 1 7 12 13 16 18 40 29 15

% paste -d' ' <(nl id.txt | cut -f1) <(cut -d' ' -f2- file.txt) 
 1 0 10 12 23 18 17 25
 2 1 7 12 13 16 18 40 29 15
 3 10 12 23 18 17 25
 4 1 7 12 13 16 18 40 29 15
1
ответ дан 7 December 2019 в 15:34
awk 'BEGIN {OFS=""} {print "s/^", $0, "/", ++count, "/"}' > pattern.sed ids.txt

Это собирается считать Ваш "идентификационный" файл и создает список идентификатора для использования замены и поиска sed.

$ cat pattern.sed 
s/^564/1/
s/^565/2/
...

Если Ваши идентификаторы не уникальны, можно использовать:

sort ids.txt | uniq | awk 'BEGIN {OFS=""} {print "s/^", $0, "/", ++count, "/"}' > pattern.sed 

для создания этого более эффективным затем работайте:

$ sed -i.bk -f pattern.sed file 

$ cat file
2 0 10 12 23 18 17 25
1 1 7 12 13 16 18 40 29 15
1 1 7 12 13 16 18 40 29 11111
1 1 7 12 13 16 18 40 29 15555
2 0 10 12 23 18 17 2555
...

Если Вы хотите отсортировать заключительное использование файла sort -k1,1 file > file.sorted.

0
ответ дан 7 December 2019 в 15:34

Другие вопросы по тегам:

Похожие вопросы: