Подтвердить что ты не робот

Есть ли способ игнорировать строки заголовков в сортировке UNIX?

У меня есть файл с фиксированной шириной, который я пытаюсь сортировать с помощью утилиты сортировки UNIX (Cygwin, в моем случае).

Проблема заключается в том, что в верхней части файла находится двухстрочный заголовок, который сортируется в нижней части файла (поскольку каждая строка заголовка начинается с двоеточия).

Есть ли способ рассказать сортировку либо "передать первые две строки по несортированному", либо указать порядок, который сортирует строки двоеточия в верхней части - остальные строки всегда начинаются с 6-значного числа (что фактически ключ, который я сортирую), если это помогает.

Пример:

:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
500123TSTMY_RADAR00
222334NOTALINEOUT01
477821USASHUTTLES21
325611LVEANOTHERS00

должен сортировать по:

:0:12345
:1:6:2:3:8:4:2
010005TSTDOG_FOOD01
222334NOTALINEOUT01
325611LVEANOTHERS00
477821USASHUTTLES21
500123TSTMY_RADAR00
4b9b3361

Ответ 1

(head -n 2 <file> && tail -n +3 <file> | sort) > newfile

Скобки создают подоболочку, завершая stdout, чтобы вы могли ее перенести или перенаправить, как если бы она появилась из одной команды.

Ответ 2

Если вы не против использования awk, вы можете использовать awk встроенные возможности канала

например.

extract_data | awk 'NR<3{print $0;next}{print $0| "sort -r"}' 

Это печатает первые две строки дословно, а остальные - через sort.

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

Ответ 3

Вот версия, которая работает с данными по каналам:

(read -r; printf "%s\n" "$REPLY"; sort)

Если ваш заголовок имеет несколько строк:

(for i in $(seq $HEADER_ROWS); do read -r; printf "%s\n" "$REPLY"; done; sort)

Это решение от здесь

Ответ 4

Вы можете использовать tail -n +3 <file> | sort ... (хвост выведет содержимое файла из третьей строки).

Ответ 5

head -2 <your_file> && nawk 'NR>2' <your_file> | sort

Пример:

> cat temp
10
8
1
2
3
4
5
> head -2 temp && nawk 'NR>2' temp | sort -r
10
8
5
4
3
2
1

Ответ 6

Требуется только 2 строки кода...

head -1 test.txt > a.tmp; 
tail -n+2 test.txt | sort -n >> a.tmp;

Для числовых данных требуется -n. Для альфа-сортировки -n не требуется.

Файл примера:
$ cat test.txt

заголовок
8
5
100
1
-1

Результат:
$ cat a.tmp

заголовок
-1
1
5
8
100

Ответ 7

Итак, здесь функция bash, где аргументы в точности похожи на sort. Вспомогательные файлы и трубы.

function skip_header_sort() {
    if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then
        local file=${@: -1}
        set -- "${@:1:$(($#-1))}"
    fi
    awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file
}

Как это устроено. Эта строка проверяет, есть ли хотя бы один аргумент и является ли последний аргумент файлом.

    if [[ $# -gt 0 ]] && [[ -f ${@: -1} ]]; then

Это сохраняет файл в отдельный аргумент. Так как мы собираемся стереть последний аргумент.

        local file=${@: -1}

Здесь мы удалим последний аргумент. Так как мы не хотим передавать это как аргумент сортировки.

        set -- "${@:1:$(($#-1))}"

Наконец, мы выполняем часть awk, передавая аргументы (минус последний аргумент, если это был файл) для сортировки в awk. Это было изначально предложено Дейвом и модифицировано, чтобы принимать аргументы сортировки. Мы полагаемся на тот факт, что $file будет пустым, если мы передаем по трубопроводу, поэтому игнорируется.

    awk -vsargs="$*" 'NR<2{print; next}{print | "sort "sargs}' $file

Пример использования с разделенным запятыми файлом.

$ cat /tmp/test
A,B,C
0,1,2
1,2,0
2,0,1

# SORT NUMERICALLY SECOND COLUMN
$ skip_header_sort -t, -nk2 /tmp/test
A,B,C
2,0,1
0,1,2
1,2,0

# SORT REVERSE NUMERICALLY THIRD COLUMN
$ cat /tmp/test | skip_header_sort -t, -nrk3
A,B,C
0,1,2
2,0,1
1,2,0

Ответ 8

С Python:

import sys
HEADER_ROWS=2

for _ in range(HEADER_ROWS):
    sys.stdout.write(next(sys.stdin))
for row in sorted(sys.stdin):
    sys.stdout.write(row)

Ответ 9

Здесь bash функция оболочки, полученная из других ответов. Он обрабатывает файлы и каналы. Первый аргумент - имя файла или '-' для stdin. Остальные аргументы передаются для сортировки. Несколько примеров:

$ hsort myfile.txt
$ head -n 100 myfile.txt | hsort -
$ hsort myfile.txt -k 2,2 | head -n 20 | hsort - -r

Функция оболочки:

hsort ()
{
   if [ "$1" == "-h" ]; then
       echo "Sort a file or standard input, treating the first line as a header.";
       echo "The first argument is the file or '-' for standard input. Additional";
       echo "arguments to sort follow the first argument, including other files.";
       echo "File syntax : $ hsort file [sort-options] [file...]";
       echo "STDIN syntax: $ hsort - [sort-options] [file...]";
       return 0;
   elif [ -f "$1" ]; then
       local file=$1;
       shift;
       (head -n 1 $file && tail -n +2 $file | sort $*);
   elif [ "$1" == "-" ]; then
       shift;
       (read -r; printf "%s\n" "$REPLY"; sort $*);
   else
       >&2 echo "Error. File not found: $1";
       >&2 echo "Use either 'hsort <file> [sort-options]' or 'hsort - [sort-options]'";
       return 1 ;
   fi
}

Ответ 10

Это то же самое, что и ответ Яна Шербина, но моя реализация: -

cut -d'|' -f3,4,7 $arg1 | uniq > filetmp.tc
head -1 filetmp.tc > file.tc;
tail -n+2 filetmp.tc | sort -t"|" -k2,2 >> file.tc;

Ответ 11

В простых случаях sed может выполнить работу элегантно:

    your_script | (sed -u 1q; sort)

или эквивалентно,

    cat your_data | (sed -u 1q; sort)

Ключ находится в 1q - печатать первую строку (заголовок) и выходить (оставляя оставшиеся данные для sort).

Для приведенного примера 2q сделает 2q дело.

Переключатель -u (небуферизованный) необходим для тех sed (в частности, для GNU), которые в противном случае считывали бы входные данные кусками, тем самым потребляя данные, которые вы хотите вместо этого пройти через sort.

Ответ 12

cat file_name.txt | sed 1d | sort 

Это сделает то, что вы хотите.