Есть ли способ, чтобы игнорировать строки заголовка в каком-то ЮНИКСЕ?
у меня есть файл с фиксированной шириной поля, который я пытаюсь отсортировать с помощью утилиты сортировки UNIX (Cygwin, в моем случае).
проблема в том, что в верхней части файла есть двухстрочный заголовок, который сортируется в нижней части файла (поскольку каждая строка заголовка начинается с двоеточия).
есть ли способ сказать sort либо "передать первые две строки через несортированные", либо указать порядок, который сортирует строки двоеточия сверху - остальные строки всегда начинаются с a 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
11 ответов:
(head -n 2 <file> && tail -n +3 <file> | sort) > newfile
скобки создают подобласть, обертывая stdout, чтобы вы могли передать его или перенаправить, как если бы он пришел из одной команды.
если вы не возражаете против использования
awk
, вы можете воспользоватьсяawk
встроенные способности трубынапример.
extract_data | awk 'NR<3{print ;next}{print | "sort -r"}'
это печатает первые две строки дословно и трубы остальные через
sort
.обратите внимание, что это имеет очень специфическое преимущество быть в состоянии выборочно сортировать детали конвейерного ввода. все остальные предложенные методы будут сортировать только простые файлы, которые могут быть прочитаны несколько раз. Это работает на что угодно.
вот версия, которая работает на водопроводной данные:
(read -r; printf "%s\n" "$REPLY"; sort)
Если ваш заголовок содержит несколько строк:
(for i in $(seq $HEADER_ROWS); do read -r; printf "%s\n" "$REPLY"; done; sort)
это решение от здесь
можно использовать
tail -n +3 <file> | sort ...
(хвост будет выводить содержимое файла из 3-й строки).
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
Это займет всего 2 строки кода...
head -1 test.txt > a.tmp; tail -n+2 test.txt | sort -n >> a.tmp;
для числовых данных требуется-n. Для Альфа-сортировки-n не требуется.
пример файла:
$ кошачий тест.txtзаголовок
8
5
100
1
-1результат:
$ коту.ТМПзаголовок
-1
1
5
8
100
С 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)
вот функция оболочки bash, полученная из других ответов. Он обрабатывает как файлы, так и трубы. Первый аргумент-это имя файла или '-' для ввода. Остальные аргументы передаются для сортировки. Пара примеров:
$ hsort myfile.txt $ head -n 100 myfile.txt | hsort - $ hsort myfile.txt -k 2,2 | head -n 20 | hsort - -r
функция Shell:
hsort () { if [ "" == "-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 "" ]; then local file=; shift; (head -n 1 $file && tail -n +2 $file | sort $*); elif [ "" == "-" ]; then shift; (read -r; printf "%s\n" "$REPLY"; sort $*); else >&2 echo "Error. File not found: "; >&2 echo "Use either 'hsort <file> [sort-options]' or 'hsort - [sort-options]'"; return 1 ; fi }
Это то же самое, что и ответ Яна Щербина, но моя реализация :-
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;
Итак, вот функция bash, где аргументы точно такие же, как сортировка. Поддержка файлов и каналов.
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