У меня есть файл csv, скажем, строки
cat lines
1:abc
6:def
17:ghi
21:tyu
Я хотел добиться чего-то вроде этого
1:6:abc
6:17:def
17:21:ghi
21::tyu
Пробовал приведенный ниже код, не работал
awk 'BEGIN{FS=OFS = ":"}NR>1{nln=$1;cl=$2}NR>0{print $1,nln,$2}' lines
1::abc
6:6:def
17:17:ghi
21:21:tyu
Не могли бы вы помочь?
1-е решение: Вот решение tac
+ awk
+ tac
. Написано и протестировано только с показанными образцами.
tac Input_file |
awk '
BEGIN{
FS=OFS = ":"
}
{
prev=(prev?$2=prev OFS $2:$2=OFS $2)
}
{
prev=$1
}
1
' | tac
Объяснение: Добавлено подробное объяснение приведенного выше кода.
tac Input_file | ##Printing lines from bottom to top of Input_file.
awk ' ##Getting input from previous command as input to awk.
BEGIN{ ##Starting BEGIN section from here.
FS=OFS = ":" ##Setting FS and OFS as colon here.
}
{
prev=(prev?$2=prev OFS $2:$2=OFS $2) ##Creating prev if previous NOT NULL then add its value prior to $2 with prev OFS else add OFS $2 in it.
}
{
prev=$1 ##Setting prev to $1 value here.
}
1 ##printing current line here.
' | tac ##Sending awk output to tac to make it in actual sequence.
2-е решение: Добавляем только awk
решение с 2-кратной передачей ему Input_file.
awk '
BEGIN{
FS=OFS = ":"
}
FNR==NR{
if (FNR>1){
arr[FNR-1]=$1
}
next
}
{
$2=(FNR in arr)?(arr[FNR] OFS $2):OFS $2
}
1
' Input_file Input_file
Вот потенциальное решение AWK:
cat lines
1:abc
6:def
17:ghi
21:tyu
awk -F":" '{num[NR]=$1; letters[NR]=$2}; END{for(i=1;i<=NR;i++) print num[i] ":" num[i + 1] ":" letters[i]}' lines
1:6:abc
6:17:def
17:21:ghi
21::tyu
Отформатировано:
awk '
BEGIN {FS=OFS = ":"}
{
num[NR] = $1;
letters[NR] = $2
}
END {for (i = 1; i <= NR; i++)
print num[i], num[i + 1], letters[i]
}
' lines
1:6:abc
6:17:def
17:21:ghi
21::tyu
В основном это ваше решение, но я изменил порядок блоков кода и добавил блок END
для вывода последней записи, вы были близки:
awk 'BEGIN{FS=OFS = ":"}FNR>1{print p,$1,q}{p=$1;q=$2}END{print p,"",q}' file
Объяснение:
$ awk 'BEGIN {
FS=OFS = ":" # delims
}
FNR>1 { # all but the first record
print p,$1,q # output $1 and $2 from the previous round
}
{
p=$1 # store for the next round
q=$2
}
END { # gotta output the last record in the END
print p,"",q # "" feels like cheating
}' file
Выход:
1:6:abc
6:17:def
17:21:ghi
21::tyu