Как сортировать по строке из терминала

Большинство людей не обращают внимания на то, что Ubuntu Touch, поскольку он работает на официально поддерживаемых устройствах, до сих пор работает почти на двух операционных системах одновременно, а не на одном.

У вас работает Ubuntu Touch и быть вашим интерфейсом, и у вас есть контейнер LXC, предоставляющий услуги Android. Хотя контейнер LXC не является полноценным Android с пользовательским интерфейсом, эта настройка потребляет немного больше ресурсов и усложняет перенос для устройств, отличных от Android.

1
задан 13 April 2017 в 15:24

8 ответов

Это должно делать то, что вы ищете. Он прочитает файл (test.txt) и создаст выходной файл (sorted.txt) с отсортированными строками в том же порядке, что и в исходном файле.

while read line; do j=$(echo "$line" | sed -e 's/,/\n/g' | sort -n); echo "$j" 
    | sed -e 's/ /,/g' >> sorted.txt; done < test.txt
7
ответ дан 24 May 2018 в 09:29
  • 1
    Вы заметили пробел в первой строке 2,4,5 14,9? – Avinash Raj 14 April 2014 в 09:36
  • 2
    плохое использование кошки! Для работы в каждой строке выполните while read line; do ...; done < test.txt – Fredrik Pihl 14 April 2014 в 12:30
  • 3
    @FredrikPhil: Спасибо. Я отредактировал свой ответ. – jkt123 14 April 2014 в 14:11

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

Существует множество доступных утилит обработки текста, которые позволят вам сделать это (в том числе sed, awk или даже простой tr), однако сама оболочка bash может многое сделать В наше время. Предполагая, что вы хотите, чтобы вход был разделен запятыми (в вашем примере есть сочетание разделителей запятых и пробелов), вы можете сделать:

while read line; do 
  sorted=$(sort -g -- <<< "${line//,/$'\n'}")
  printf -- "${sorted//$'\n'/,}\n"
done < file

Если вы строк внутри файла 1] необходимо обрабатывать разделители пробелов на входе, тогда вы можете добавить их как часть списка символов [, ] для замены входной подстроки:

while read line; do 
  sorted=$(sort -g -- <<< "${line//[, ]/$'\n'}")
  printf -- "${sorted//$'\n'/,}\n"
done < file

(обратите внимание, что вывод остается строго комматическим, хотя и ограничено).

4
ответ дан 24 May 2018 в 09:29

python -c "your code here" input.txt

Или, если ваша программа имеет несколько строк и eval() слишком медленно:

python yourprogram.py input.txt

Этот oneliner работает:

python -c "for l in open('input.txt'):print(','.join(sorted(l.strip().split(','), key=int)))"
3
ответ дан 24 May 2018 в 09:29
  • 1
    OP не ищет решение на основе python. – jobin 14 April 2014 в 21:43
  • 2
    Да, он: «просто хочу посмотреть, можно ли это сделать из терминала, сценариев bash или любого другого . & Quot; – Cees Timmerman 14 April 2014 в 22:01
  • 3
    Лол, ты прибил его! – jobin 14 April 2014 в 22:04

Использование tr и sed

Похоже в духе того, что написал jkt123:

while read i; do tr , \\n <<< $i | sort -n | tr \\n , | sed 's/,$//'; done

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

Использование массивов bash

Вот другой подход к решению этой проблемы с объединением с запятыми: 5]

while read i; do j=( $(tr , \\n <<< $i | sort -n) ); ( IFS=,; echo "${j[*]}"; ); done

Или написано с помощью оберток строк:

while read i
do
   j=( $(tr , \\n <<< $i | sort -n) )
   ( IFS=,; echo "${j[*]}"; )
done

Он использует массив bash для хранения результата сортированной строки и использует способ, с помощью которого bash расширяет массивы в строковые литералы используя специальную переменную IFS.

3
ответ дан 24 May 2018 в 09:29

Здесь представлено решение awk,

while read -r line; do (echo $line | awk '{ n=split($1,a,","); asort(a); for(i=0;i<=n;i++) { print a[i];}}') | xargs | sed -e 's/ /,/g'; done < text.txt

Объяснение:

awk '{ n=split($1,a,","); asort(a); for(i=0;i<=n;i++) { print a[i];}}' awk Разделяет поле 1 в соответствии с разделителем , и сохраняет каждое значение в массив a, наконец, верхняя позиция сохраняется в переменной n. Следующая функция asort(a) сортирует значения массива. Затем цикл for внутри команды awk печатает отсортированные значения в формате записи по записи. xargs | sed -e 's/ /,/g' xargs объединяет все строки в одну строку. sed -e 's/ /,/g' Он заменяет пробелы запятыми , while read -r line;. Все вышеперечисленные функции awk, xargs, sed выполняются по строкам с помощью цикла while.
3
ответ дан 24 May 2018 в 09:29

Вы можете сделать это легко, используя perl

, если у вас есть файл text.txt

cat text.txt

1,5,7,8,3,6
10,34,67,1,2,0,5

Теперь следующий код Perl будет сортировать строки в text.txt [!d2 ]

 perl -i -e 'while(<>){chomp; my @sorted = sort { $a <=> $b } split(",", $_); print join (",", @sorted); print "\n"}' text.txt

После сортировки

cat text.txt

1,3,5,6,7,8
0,1,2,5,10,34,67
2
ответ дан 24 May 2018 в 09:29
  • 1
    Это можно значительно сократить с помощью perl -i -lne 'print join (",", sort {$a <=> $b} split(",", $_));' text.txt. Флаг -n совпадает с while(<>){}, а -l добавляет \n к каждому вызову печати и также активирует неявный chomp(). – terdon♦ 14 April 2014 в 11:00

Самое короткое решение, использующее perl oneliner:

perl -ne 'print join(",", sort { $a <=> $b } split(/,|\n/))."\n"' text.txt
2
ответ дан 24 May 2018 в 09:29
  • 1
    Хе, я оставил свой ответ открытым на некоторое время и не видел этого, но не самый короткий: P – terdon♦ 14 April 2014 в 10:39
  • 2
    Je m'incline ;-) – Sylvain Pineau 14 April 2014 в 10:41

Мне тоже нужна эта функциональность, и найденное мной решение выглядит следующим образом (если данные находятся в тестовом файле):

cat test | while read line; do echo $(echo $line | datamash -t',' transpose |sort -g| datamash -t',' transpose); done
1
ответ дан 24 May 2018 в 09:29

Другие вопросы по тегам:

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