Bash 在'之后完成行'|&引用;具有上/下行中特定数据的字符
我有一个数据集,看起来与下面的类似 我需要完成“|”之后的每一行,在“|”之前的值与实际行匹配的特定行之前/之后的值相同 如果能用bash/shell脚本或者excel来完成,我将不胜感激Bash 在'之后完成行'|&引用;具有上/下行中特定数据的字符,bash,shell,dataset,Bash,Shell,Dataset,我有一个数据集,看起来与下面的类似 我需要完成“|”之后的每一行,在“|”之前的值与实际行匹配的特定行之前/之后的值相同 如果能用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| 1
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
它是如何工作的? 这将对输入文件进行反向排序,使其成为
/tmp/reversedinput
:
11635_7|20
11635_7|
11610_3|10
11610_3|
11510_105|20
11510_105|
...
现在,逐行读取文件(从顶部开始),如果当前迭代中的行在管道字符之后没有任何内容,只需将其替换为上面的行即可。这就是awk
片段所做的。所以你得到了/tmp/reversedoutput
最后,只需按正确的顺序对其进行排序,就可以得到outputfile
它是如何工作的? 这将对输入文件进行反向排序,使其成为
/tmp/reversedinput
:
11635_7|20
11635_7|
11610_3|10
11610_3|
11510_105|20
11510_105|
...
现在,逐行读取文件(从顶部开始),如果当前迭代中的行在管道字符之后没有任何内容,只需将其替换为上面的行即可。这就是awk
片段所做的。所以你得到了/tmp/reversedoutput
最后,只需按正确的顺序对其进行排序,就可以得到outputfile
尝试以下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)与当前文件中的记录编号相同。无论如何,我们只是记住了值散列中的值。Awk再次遍历该文件,打印每一行及其相关值。尝试此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)与当前文件中的记录编号相同。无论如何,我们只是记住了值散列中的值。Awk再次检查文件,打印每一行及其相关值。此excel函数将解决此问题,只需将“输入”粘贴到单元格A2中,然后在单元格B2中使用此函数,然后填充,直到到达B34(在本例中) 它是如何工作的 它首先检查字符串是否需要修改:
LEN(A2)=FIND("|",A2)
如果是,则将字符串的前半部分与前一行进行比较:
IF(MID(A2,1,FIND("|",A2))=IFERROR(MID(A1,1,FIND("|",A1)),"")`
注意:“IFERROR”用于处理第一行的情况,因为MID函数将返回#值
如果匹配,则将当前字符串的前半部分与前一个字符串的后半部分合并(这可能是过分的,因为两行应该相同)
输出:
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
此excel函数将解决此问题,只需将“输入”粘贴到单元格A2中,然后在单元格B2中使用此函数,然后填充,直到到达B34(在本例中) 它是如何工作的 它首先检查字符串是否需要修改:
LEN(A2)=FIND("|",A2)
如果是,则将字符串的前半部分与前一行进行比较:
IF(MID(A2,1,FIND("|",A2))=IFERROR(MID(A1,1,FIND("|",A1)),"")`
注意:“IFERROR”用于处理第一行的情况,因为MID函数将返回#值
如果匹配,则将当前字符串的前半部分与前一个字符串的后半部分合并(这可能是过分的,因为两行应该相同)
输出:
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
今后,请将示例数据量减少到说明您试图解决的问题的最少行数,并包括您编写解决方案的最佳尝试。在这里发布更多Qs之前,请阅读和。祝你好运。今后,请将示例数据的数量减少到说明你试图解决的问题的最小行数,并包括你编写解决方案的最佳尝试。在这里发布更多Qs之前,请阅读和。祝你好运