AWK распечатывает каждый второй столбец, начиная с последнего столбца (и рядом с последним столбцом) для N целых чисел (печать справа налево) - PullRequest
0 голосов
/ 04 октября 2019

Надеюсь, кто-то в мире сможет мне помочь, а кому-то еще с похожей проблемой найти простое решение для сбора данных. Я потратил часы на то, чтобы решить один вопрос, и я решил, что это простая проблема, включающая awk, файл csv и сохранение вывода в виде переменной bash. Короче, вот гайка ...

Миссии:

1) Для вывода каждого другого столбца, начиная с ПОСЛЕДНЕЙ КОЛОННЫ, с определенным количеством итераций.

2) Чтобы вывести все остальные столбцы, начиная от СЛЕДУЮЩАЯ до ПОСЛЕДНЕЙ КОЛОННЫ, с определенным количеством итераций.

Данные (file.csv):

@12@SayWhat@2@4@2.25@3@1.5@1@1@1@3.25
@7@Smarty@9@6@5.25@5@4@4@3@2@3.25
@4@IfYouLike@4@1@.2@1@.5@2@1@3@3.75
@3@LaughingHard@8@8@13.75@8@13@6@8.5@4@6
@10@AtFunny@1@3@.2@2@.5@3@3@5@6.5
@8@PunchLines@7@7@10.25@7@10.5@8@11@6@12.75

Желаемые результаты для Миссии 1:

  2@2.25@1.5@1@3.25
  9@5.25@4@3@3.25
  4@.2@.5@1@3.75
  8@13.75@13@8.5@6
  1@.2@.5@3@6.5
  7@10.25@10.5@11@12.75

Желаемые результаты для Миссии 2:

  SayWhat@4@3@1@1
  Smarty@6@5@4@2
  IfYouLike@1@1@2@3
  LaughingHard@8@8@6@4
  AtFunny@3@2@3@5
  PunchLines@7@7@8@6

Мои попытки:

Закрытие, которое я пришел к решению любой из вышеперечисленных проблем, является уродливой трубкой (что нормально для снятия шкуры с кошки) для Миссии 1. Однако она не использует никаких заявленных итераций (должно быть 5). Кроме того, я полностью потерялся при решении Миссии 2.

Любая помощь, чтобы упростить нижеприведенное и решение Миссии 2, будет благодарна HELLA!

outcome=$( awk 'BEGIN {FS = "@"} {for (i = 0; i <= NF; i += 2) printf ("%s%c", $(NF-i), i + 2 <= NF ? "@" : "\n");}' file.csv | sed 's/@@.*//g' | awk -F@ '{for (i=NF;i>0;i--){printf $i"@"};printf "\n"}' | sed 's/@$//g' | awk -F@ '{$1="";print $0}' OFS=@ | sed 's/^@//g' );

Кроме того, если делать цикл дляопределенное количество итераций полезно для решения этой проблемы, тогда магическое число равно 5. Возможно, решением может быть цикл for, который считает справа налево и пропускает каждый второй столбец как 1 итерацию, причем начальный столбец объявлен как awkпеременная (просто мысль, что я не знаю, как это сделать)

Спасибо за просмотр этой проблемы.

Ответы [ 3 ]

2 голосов
/ 05 октября 2019

Пример данных:

$ cat mission.dat
@12@SayWhat@2@4@2.25@3@1.5@1@1@1@3.25
@7@Smarty@9@6@5.25@5@4@4@3@2@3.25
@4@IfYouLike@4@1@.2@1@.5@2@1@3@3.75
@3@LaughingHard@8@8@13.75@8@13@6@8.5@4@6
@10@AtFunny@1@3@.2@2@.5@3@3@5@6.5
@8@PunchLines@7@7@10.25@7@10.5@8@11@6@12.75

Одно awk решение:

ПРИМЕЧАНИЕ: OP может добавить логику для проверки входных параметров.

$ cat mission
#!/bin/bash
# format: mission { 1 | 2 } { number_of_fields_to_display }
mission=${1}                       # assumes user inputs "1" or "2"
offset=$(( mission - 1 ))           # subtract one to determine awk/NF offset
iteration_count=${2}               # assume for now this is a positive integer

awk -F"@" -v offset=${offset} -v itcnt=${iteration_count} 'BEGIN { OFS=FS }

{ # we will start by counting fields backwards until we run out of fields
  # or we hit "itcnt==iteration_count" fields

  loopcnt=0
  for (i=NF-offset ; i>=0; i-=2)   # offset=0 for mission=1; offset=1 for mission=2
      { loopcnt++
        if (loopcnt > itcnt)
          break
        fstart=i                    # keep track of the field we want to start with
      }

  # now printing our fields starting with field # "fstart";
  # prefix the first printf with a empty string, then each successive
  # field is prefixed with OFS=@

  pfx = ""
  for (i=fstart; i<= NF-offset; i+=2)
      { printf "%s%s",pfx,$i
        pfx=OFS
      }

  # terminate a line of output with a linefeed
  printf "\n"
}
' mission.dat

Некоторый тестработает:

###### mission #1

# with offset/iteration = 4

$ mission 1 4
2.25@1.5@1@3.25
5.25@4@3@3.25
.2@.5@1@3.75
13.75@13@8.5@6
.2@.5@3@6.5
10.25@10.5@11@12.75

#with offset/iteration = 5

$ mission 1 5
2@2.25@1.5@1@3.25
9@5.25@4@3@3.25
4@.2@.5@1@3.75
8@13.75@13@8.5@6
1@.2@.5@3@6.5
7@10.25@10.5@11@12.75

# with offset/iteration = 6

$ mission 1 6
12@2@2.25@1.5@1@3.25
7@9@5.25@4@3@3.25
4@4@.2@.5@1@3.75
3@8@13.75@13@8.5@6
10@1@.2@.5@3@6.5
8@7@10.25@10.5@11@12.75

###### mission #2

# with offset/iteration = 4

$ mission 2 4
4@3@1@1
6@5@4@2
1@1@2@3
8@8@6@4
3@2@3@5
7@7@8@6

# with offset/iteration = 5

$ mission 2 5
SayWhat@4@3@1@1
Smarty@6@5@4@2
IfYouLike@1@1@2@3
LaughingHard@8@8@6@4
AtFunny@3@2@3@5
PunchLines@7@7@8@6

# with offset/iteration = 6;
# notice we pick up field #1 = empty string so output starts with a '@'

$ mission 2 6
@SayWhat@4@3@1@1
@Smarty@6@5@4@2
@IfYouLike@1@1@2@3
@LaughingHard@8@8@6@4
@AtFunny@3@2@3@5
@PunchLines@7@7@8@6
2 голосов
/ 04 октября 2019

Конечно, есть более изящные способы сделать это, но я на самом деле не awk человек:

Часть 1:

awk -F@ '{ x = ""; for (f = NF; f > (NF - 5 * 2); f -= 2) { x = x ? $f "@" x : $f ; } print x }' file.csv

Вывод:

2@2.25@1.5@1@3.25
9@5.25@4@3@3.25
4@.2@.5@1@3.75
8@13.75@13@8.5@6
1@.2@.5@3@6.5
7@10.25@10.5@11@12.75

Часть 2:

awk -F@ '{ x = ""; for (f = NF - 1; f > (NF - 5 * 2); f -= 2) { x = x ? $f "@" x : $f ; } print x }' file.csv

Вывод:

SayWhat@4@3@1@1
Smarty@6@5@4@2
IfYouLike@1@1@2@3
LaughingHard@8@8@6@4
AtFunny@3@2@3@5
PunchLines@7@7@8@6

Литерал 5 в каждом из них является вашим «числом итераций».

1 голос
/ 05 октября 2019

это, вероятно, не то, что вы спрашиваете, но, возможно, даст вам представление.

$ awk -F_ -v skip=4 -v endoff=0 '
      BEGIN {OFS=FS} 
            {offset=(NF-endoff)%skip; 
             for(i=offset;i<=NF-endoff;i+=skip) printf "%s",$i (i>=(NF-endoff)?ORS:OFS)}' file

112_116_120
122_126_130
132_136_140
142_146_150

вы указываете количество пропусков между столбцами и конечное смещение в качестве входных переменных. Здесь для последнего столбца смещение конца равно нулю, а пропускаемый столбец равен 4.

Для ясности я использовал входной файл

$ cat file
_111_112_113_114_115_116_117_118_119_120
_121_122_123_124_125_126_127_128_129_130
_131_132_133_134_135_136_137_138_139_140
_141_142_143_144_145_146_147_148_149_150

, смена FS для вашего формата должна работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...