awk -F', *_?' -v OFS=, '
NR==1 {
for (i=1;i<=NF;i++) {
if ($i == "post_id") {
$i = "page ID" OFS "post ID";
col=$1;
};
};
print;
next
};
{
split($col,a,/_/);
$col=a[1] OFS a[2];
print;
};
' FB_Dataset.csv
Поскольку данные поля, которые вы показали, имеют несовместимый формат (некоторые с начальными пробелами, некоторые начинаются с подчеркивания, возможно, некоторые с обоими ), этот awk
скрипт использует регулярное выражение, *_?
(" запятая, за которой следует ноль -или -пробелов и, возможно, символ подчеркивания" )в качестве разделителя полей(FS
).
Он также устанавливает разделитель полей вывода(OFS
)в виде запятой.
При чтении ввода он обрабатывает первую строку (, заголовки CSV )и все остальные строки по-разному:
Для первой строки(NR==1
)он проверяет значения каждого поля в поисках строки "post_id"
. Если он находит эту строку, он изменяет значение этого поля, чтобы оно имело два новых имени поля(page ID
и post ID
), разделенных OFS
. Он также сохраняет порядковый номер этого поля в переменной col
для последующего использования. Наконец, он печатает измененную строку.
Предполагается, что имена полей уникальны, как и должно быть для действительных файлов CSV. Это не будет работать правильно, если более одного поля имеют имя post_id
.
Для остальных строк поле $col
разбивается на массив a
, используя символы подчеркивания(_
)в качестве разделителя.Затем он заменяет $col первыми двумя элементами этого массива, разделенными OFS
. Затем он печатает измененную строку.
Пример ввода:
A,B,C,post_id,D,E,F
a,b,c,86680728811_272953252761568,d,e,f
a,b,c, 86680728811_273859942672742,d,e,f
a,b,c,86680728811_281125741936891,d,e,f
Пример вывода:
A,B,C,page ID,post ID,D,E,F
a,b,c,86680728811,272953252761568,d,e,f
a,b,c,86680728811,273859942672742,d,e,f
a,b,c,86680728811,281125741936891,d,e,f
В строке заголовка поле post_id
было преобразовано в два поля(page ID
и post ID
), а в данных CSV соответствующее поле было разделено на два поля.
Кстати, поскольку скрипт ищет совпадающее имя поля(post_id
)в строке заголовка, он будет работать с любым количеством полей до и/или после поля, которое мы хотим разделить. В этом образце данных было обнаружено, что четвертое поле содержит нужное нам имя, поэтомуcol=4
Обратите внимание, что $i
и $col
в awk не означают одно и то же, что и в оболочке.
i
и col
. В awk
они означают «значение поля, порядковый номер которого равен значению переменнойi
(или переменной col
)». то есть это доступ к полю через косвенность.
напр. если i=1
, то $i
означает «значение в поле 1», что совпадает с $1
.
Это полезно, если, например, вам нужно выполнить арифметические действия над номером поля. В awk NF
— это автоматически -созданная переменная, содержащая порядковый номер последнего поля текущей входной строки. поэтому $NF
означает «значение в последнем поле», а $(NF-1)
означает «значение во втором -последнем поле» и так далее.