У меня есть текстовый файл со строками и столбцами внутри этих строк. Я хочу, по сути, повторить функцию Excel "заполнить вниз". Другими словами, если в строке есть пустая "ячейка", она будет смотреть на строку выше и заполнять значение в соответствующем поле над ней. Пример, где "^" используется в качестве разделителя столбцов:
London^Paris^Moscow^Berlin
^^Melbourne^New York^Washington
^^^Sydney^Singapore^New Delhi
^^New York^Washington
Kuala Lumpur^Bangkok^Hong Kong
^^^^Johannesburg^Sydney^Singapore^New Delhi
Amsterdam
^^Bucharest
... становится (для ясности заполненные пункты ЗАГЛАВНЫМИ БУКВАМИ):
London^Paris^Moscow^Berlin
LONDON^PARIS^Melbourne^New York^Washington
LONDON^PARIS^MMELBOURNE^Sydney^Singapore^New Delhi
LONDON^PARIS^New York^Washington
Kuala Lumpur^Bangkok^Hong Kong
KUALA LUMPUR^BANGKOK^HONG KONG^^Johannesburg^Sydney^Singapore^New Delhi
Amsterdam
AMSTERDAM^^Bucharest
Так что по сути функция заключается в том, чтобы идентифицировать любое пустое поле и, если оно есть, вытащить значение из соответствующего поля над ним. Важно иметь возможность указывать разделители полей/столбцов. Есть идеи?
решение1
awk -F'^' -v OFS='^' \
'{
for (i = 1; i <= NF; i++) {
if ($i == "") $i = save[i]
else save[i] = $i
}
for (i = NF+1; i <= 99; i++) save[i] = ""
print
}'
Здесь используется массив, который называется save
для сохранения значений из одной строки в другую (заполнение вниз). Все в awk
неявно инициализируется значением null, поэтому save
массив будет пустым, пока ему не будут назначены данные. (Поэтому любые пустые поля в первой строке останутся пустыми, поскольку нет никаких предыдущих данных для копирования в них вниз.)
Для каждой строки,
- Для каждого поля, которое существует в этой строке (
for (i = 1; i <= NF; i++)
),- если он пуст, заполните его сохраненным (скопированным) значением для этого столбца,
- в противном случае сохраните текущее значение для возможного использования в последующих строках.
Затем сотрите
save
массив для всех столбцов, которых нет в текущей строке. Например, когда мы добираемся до строки 4 (в которой всего четыре поля), мы «забываем», что столбцы 5 и 6 строки 3 содержали «Сингапур» и «Нью-Дели». А когда мы добираемся до строки 7 (в которой всего одно поле), мы «забываем», что столбец 2 строки 5 содержал «Бангкок», поэтому его нельзя ввести в строку 8 (где столбец 2 пуст).Замените
99
на наибольшее количество полей, которое вы ожидаете увидеть в одной строке (когда-либо).