В настоящее время у меня есть несколько файлов с миллионами строк, которые похожи на следующее:
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, но являюсь там какими-либо способами указать способ преобразования в текстовом файле и использовать сценарий оболочки для применения его к исходным файлам?
Спасибо.
Если Вы хотите увеличить первое поле монотонным способом, Вы не должны использовать дополнительный файл для отображения или первого поля, просто использовать 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
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
.