Сортировка файла с сохранением заголовка в качестве первой позиции с bash - PullRequest
1 голос
/ 23 апреля 2020

При сортировке файла я не сохраняю заголовок в его позиции:

file_1.tsv

Gene   Number  
a       3
u       7
b       9
sort -k1,1 file_1.tsv

Результат:

a     3
b     9
Gene  Number
u     7

Итак, я пытаюсь этот код:

sed '1d' file_1.tsv | sort -k1,1 > file_1_sorted.tsv 
first='head -1 file_1.tsv' 
sed '1 "$first"' file_1_sorted.tsv

Что я сделал, это удалил заголовок и отсортировал оставшуюся часть файла, а затем снова попытался добавить заголовок. Но я не могу выполнить эту последнюю часть, поэтому мне хотелось бы знать, как я могу скопировать заголовок исходного файла и вставить его в качестве первой строки нового файла, не подставляя его фактически всю первую строку.

Ответы [ 5 ]

4 голосов
/ 23 апреля 2020

Вы также можете сделать это:

{ head -1; sort; } < file_1.tsv

** Обновление **

Для макросов:

{ IFS= read -r header; printf '%s\n' "$header" ; sort; } < file_1.tsv
3 голосов
/ 23 апреля 2020

проще awk

$ awk 'NR==1{print; next} {print | "sort"}' file
3 голосов
/ 23 апреля 2020
$ head -1 file; tail -n +2 file | sort

Выход:

Gene   Number  
a       3
b       9
u       7
2 голосов
/ 23 апреля 2020

Не могли бы вы попробовать следующее.

awk '
FNR==1{
  first=$0
  next
}
{
  val=(val?val ORS:"")$0
}
END{
  print first
  print val | "sort"
}
'  Input_file

Логическое объяснение:

  • Проверьте условие FNR==1, чтобы увидеть, если его первая строка; затем сохраните его значения в переменной и перейдите к следующей строке на next.
  • Затем продолжайте добавлять значения всех строк к другой переменной с новой строкой до последней строки.
  • Теперь перейдите к END блок этого кода, который выполняется после прочтения Input_file, печатает значение первой строки и помещает команду sort в значение остальных строк.
1 голос
/ 23 апреля 2020

Это будет работать с использованием любого awk, сортировки и вырезания в любой оболочке на каждом поле UNIX и будет работать независимо от того, поступает ли ввод из канала (когда вы не можете прочитать его дважды) или из файла (когда вы можете) и не включает в себя awk, порождающий подоболочку:

awk -v OFS='\t' '{print (NR>1), $0}' file | sort -k1,1n -k2,2 | cut -f2-

В приведенном выше примере awk используется для обозначения 0 в начале строки заголовка и 1 перед остальными, чтобы вы могли отсортировать по это число, затем любые другие поля, которые вы хотите отсортировать, а затем снова удалите добавленное поле с вырезом. Вот оно поэтапно:

$ awk -v OFS='\t' '{print (NR>1), $0}' file
0   Gene   Number
1   a       3
1   u       7
1   b       9

$ awk -v OFS='\t' '{print (NR>1), $0}' file | sort -k1,1n -k2,2
0   Gene   Number
1   a       3
1   b       9
1   u       7

$ awk -v OFS='\t' '{print (NR>1), $0}' file | sort -k1,1n -k2,2 | cut -f2-
Gene   Number
a       3
b       9
u       7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...