Сортировка блоков данных, основанных на конкретном ряду данных

Вероятно, меня будут критиковать за это, так как это кажется несколько спорным, но если вы хотите, чтобы два пользователя были идентичны для системы, вы можете отредактировать /etc/passwd, чтобы дать им обоим одинаковый UID. UID - это то, что ядро использует для определения прав доступа к файлам и других привилегий: имя пользователя его не волнует.

Однако это может иметь странные побочные эффекты, поэтому используйте это только в том случае, если вы знаете, что делаете.

Я рекомендую вам прочитать ответы и комментарии на Почему я могу создавать пользователей с одинаковым UID?

1
27.10.2018, 21:47
3 ответа

Кажется, это помогает. Я постараюсь опубликовать более читабельную версию в ближайшее время.

$ perl -e 'while(<>){next if /^$/;push @a,$_;if(/sessionStartTime/){$k=$_}if($#a==7){$v{$k}=[@a];undef @a}}for $x(sort keys %v){for $i (0..7){print $v{$x}[$i]}print "\n"}' <input >output

Более чистая и читаемая версия. Функционально идентичны.

perl -e 'while(<>) {
             # skip any blank lines
             next if /^$/;

             # add line to array a
             push @a,$_;

             # if line holds our key value, store it 
             if(/sessionStartTime/) {
                 $k=$_;
             }

             # if we've got all 8 lines, store it in a hash, keyed on our sessionStartTime
             if($#a==7) {
                 $v{$k}=[@a];
                 undef @a;
             }
         }
         # After reaching end of file, process each key and print its 8 lines
         for $x (sort keys %v) {
             for $i (0..7) {
                 print $v{$x}[$i];
             }
             print "\n";
         }' <input  >output
0
27.01.2020, 23:31

Предполагая, что временные метки сортируются лексически в вашей локали и при наличии GNU Awk версии 4.0 или более поздней:

gawk -vRS= '
  match($0,/sessionStartTime:([^[:space:]]*)/,m) {
    a[m[1]] = $0
  } 
  END {
    PROCINFO["sorted_in"] = "@ind_str_asc" 
    for (i in a) print a[i] "\n"
  }' file

Аналогичный подход в Perl:

perl -00 -lne '
  $h{$1} = $_ if /sessionStartTime:(\S*)/
  }{
  for $k (sort keys %h) {print $h{$k}}
' file
2
27.01.2020, 23:31

В баш:

declare -a LINES
declare -A BLOCKS

IFS=$'\n'

addToBlocks() {
  if [ "$EPOCH" ]
  then
    BLOCKS["$EPOCH"]="${LINES[*]}"
  else
    echo "No sessionStartTime line for this block."
  fi
}

while read LINE
do
  SSTIME="${LINE/sessionStartTime:}"
  [ "${SSTIME}" != "$LINE" ] && EPOCH="$( date +%s -d "${SSTIME%Z}" )"
  if [ "${LINE// }" == "" ]
  then
    addToBlocks
    LINES=()
    EPOCH=""
  else
    LINES+=("${LINE}")
  fi
done
addToBlocks

for TIME in $( echo "${!BLOCKS[*]}" | sort -n )
do
  echo "${BLOCKS[$TIME]}"
  echo
done

Та же основная идея -промыть строки до тех пор, пока вы не достигнете пустой строки, после чего сохраните ее в хеше с указанием даты и времени. Как только все строки будут использованы, выведите все блоки, упорядоченные по хеш-ключу.

0
27.01.2020, 23:31

Теги

Похожие вопросы