
У меня есть текстовый файл размером более 100 МБ, каждая строка которого имеет одинаковое количество столбцов:
Column No.: 0 1 2 3 4 5 6
d x c c s b c
.............
Я хочу добавить ,
в заданных местах. Например,location = 2, 3, 5
Желаемый результат будет следующим:
Column No.: 0 1 2 3 4 5 6
d x c, c, s b, c
.............
Файл местоположения будеттекстилиcsvфайл
2
3
5
Текстовый файл должен иметь разделители.
Обновлять:
Образец данных
- Примечание: разрывы строк — это те места, где я хочу разместить разделители.
- Номер столбца — это смещение в байтах от начала строки.
решение1
Используйте Сед.
Обратите внимание, что вы не будете использовать 0 индексированных позиций, а начнете с 1. Поэтому я увеличил указанные вами числа.
Кроме того, вам придется вернуться назад к началу, так как как только вы измените первый, позиции столбцов изменятся. Поэтому используйте Sed следующим образом:
sed 's/./&,/6;s/./&,/4;s/./&,/3'
Пример:
$ echo dxccsbc
dxccsbc
$ echo dxccsbc | sed 's/./&,/6;s/./&,/4;s/./&,/3'
dxc,c,sb,c
$
- Команда
s
в Sed предназначена для замены. - Шаблон
.
соответствует любому отдельному символу. - В заменяющем
&
тексте означает «текст, который был сопоставлен», а запятая является буквальной запятой. - Числовой флаг после последнего
/
означает, что замену следует выполнять только в «n-ном» совпадении в строке.
Если ты хочешь бытьДействительноесли хотите, используйте расширение фигурных скобок Bash для создания команд Sed:
$ echo dxccsbc | sed '-es/./&,/'{6,4,3}
dxc,c,sb,c
Но это всего лишь вишенка на торте, и она, вероятно, сбивает с толку, если вы не очень хорошо понимаете и Sed, и Bash. :)
Если вы хотите извлечь список позиций из отдельного файла(как вы фактически показываете в своем вопросе), вы можете сделать это следующим образом:
sed -f <(sort -rn positionsfile | sed -n 's:^[1-9][0-9]*$:s/./\&,/&:p') file
Обратите внимание, что это специфично для Bash, поскольку он использует синтаксис подстановки процессов, который не является POSIX. Также обратите внимание, что я сделал это довольно надежным, как и все, кроме фактическогочислав файле позиций (которые не начинаются с 0) будут отброшены.
Результаты теста:
$ cat file
abcdefg
ABCDEFG
abcdelaksjdflkjsdflli
sdlfihsdlfkj
$ cat positionsfile
2
15
5
7something
01
not a number
$ sed -f <(sort -rn positionsfile | sed -n 's:^[1-9][0-9]*$:s/./\&,/&:p') file
ab,cde,fg
AB,CDE,FG
ab,cde,laksjdflkj,sdflli
sd,lfi,hsdlfkj
$
решение2
С perl
:
#!/usr/bin/env perl
my @pos;
while (<>)
{ push @pos, 1 + int; }
continue
{ last if eof; }
@pos = sort { $b cmp $a } @pos;
while (<>) {
for my $k (@pos)
{ s/^.{$k}\K/,/; }
print;
}
Запустите его так:
script.pl positions.txt file.txt