Полные строки после символа '' | "с указанием c данных из строки выше / ниже - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть набор данных, который выглядит примерно так, как показано ниже.

И мне нужно заполнить каждую строку после '|' с тем же значением строки до / после этой указанной c строки, где значение до «|» соответствует фактической строке.

Я был бы очень признателен, если бы это можно было сделать с помощью сценария bash / shell или, может быть, excel.

10166_101|  
10166_101|50  
10296_5|  
10296_5|50  
10484_5|20  
10484_5|  
10692_7|  
10692_7|10  
10742_102|  
10742_102|100  
10742_102|  
10767_13|  
10767_13|30  
10793_9|  
10793_9|50  
10863_8|40  
10863_8|  
10887_3|  
10887_3|40  
10929_2|24  
11004_2|10  
11151_5|  
11151_5|20  
11212_21|80  
11447_6|30  
11486_9|  
11486_9|80  
11510_105|20  
11510_105|  
11610_3|  
11610_3|10  
11635_7|20  
11635_7|

Поэтому данные будут выглядеть так:

10166_101|50  
10166_101|50  
10296_5|50  
10296_5|50  
10484_5|20  
10484_5|20  
10692_7|10  
10692_7|10  
10742_102|100  
10742_102|100  
10742_102|100  
10767_13|30  
10767_13|30  
10793_9|50  
10793_9|50  
10863_8|40  
10863_8|40  
10887_3|40  
10887_3|40  
10929_2|24  
11004_2|10  
11151_5|20  
11151_5|20  
11212_21|80  
11447_6|30  
11486_9|80  
11486_9|80  
11510_105|20  
11510_105|20  
11610_3|10  
11610_3|10  
11635_7|20  
11635_7|20 

Ответы [ 3 ]

1 голос
/ 24 февраля 2020

Попробуйте этот сценарий awk:

awk -F"|" -v OFS="|" '
NR == FNR { if ($2) values[$1] = $2 ;  next } 
{ print $1 , values[$1] }
' $1 $1 

Выше $ 1 считается параметром сценария - это должно быть имя файла вашего входного файла. Я передаю файл в awk дважды $1 $1, чтобы awk проанализировал файл дважды. Когда awk впервые читает файл, выражение NR == FNR имеет значение true. То есть номер текущей записи (NR) совпадает с номером записи в текущем файле. В любом случае, мы просто запоминаем значения в значениях ha sh.
Awk еще раз просматривает файл, печатая каждую строку со значением, связанным с ним.

1 голос
/ 24 февраля 2020
#!/bin/sh
sort --reverse inputfile > /tmp/reversedinput
awk -F\|   '$0=="" {next}
            $2!="" {line=$0;print line}
            $2=="" {print line;}' /tmp/reversedinput > /tmp/reversedoutput
sort /tmp/reversedoutput > outputfile

Как это работает?

Это сортирует ваш inputfile в обратном порядке, так что он становится /tmp/reversedinput:

11635_7|20
11635_7|
11610_3|10
11610_3|
11510_105|20
11510_105|
...

Теперь прочитайте файл строка за строкой (начиная с вершины) и, если строка на текущей итерации не имеет ничего после символьной трубы, просто замените ее на строку выше. Вот что делает фрагмент awk. Итак, вы получите /tmp/reversedoutput.

Наконец, просто отсортируйте его в правильном порядке, и вы получите outputfile.

0 голосов
/ 24 февраля 2020

Эта функция Excel решит проблему, просто вставьте «вход» в ячейку A2 и затем используйте эту функцию в ячейке B2, затем заполните, пока не достигнете B34 (в данном случае).

 =IF(LEN(A2)=FIND("|",A2),
      IF(MID(A2,1,FIND("|",A2))=IFERROR(MID(A1,1,FIND("|",A1)),""),
          MID(A2,1,FIND("|",A2))&MID(A1,FIND("|",A1)+1,99),
          IF(MID(A2,1,FIND("|",A2))=MID(A3,1,FIND("|",A3)),
               MID(A2,1,FIND("|",A2))&MID(A3,FIND("|",A3)+1,99),
               A2)),
     A2)

как это работает?

Сначала проверяется, нуждается ли строка в модификации:

LEN(A2)=FIND("|",A2)

, если это так, то сравнивает первую половину строки с предыдущей строкой:

IF(MID(A2,1,FIND("|",A2))=IFERROR(MID(A1,1,FIND("|",A1)),"")`

Примечание: «IFERROR» должен обрабатывать регистр первой строки, потому что функция MID вернет #Value

Если он совпадает, то он объединяет первую половину текущей строки с предыдущей строка вторая половина (это, вероятно, излишне, поскольку 2 строки должны быть идентичны).

MID(A2,1,FIND("|",A2))&MID(A1,FIND("|",A1)+1,99)

вывод:

10166_101|50
10166_101|50
10296_5|50
10296_5|50
10484_5|20
10484_5|20
10692_7|10
10692_7|10
10742_102|100
10742_102|100
10742_102|100
10767_13|30
10767_13|30
10793_9|50
10793_9|50
10863_8|40
10863_8|40
10887_3|40
10887_3|40
10929_2|24
11004_2|10
11151_5|20
11151_5|20
11212_21|80
11447_6|30
11486_9|80
11486_9|80
11510_105|20
11510_105|20
11610_3|10
11610_3|10
11635_7|20
11635_7|20
...