2013-10-09 3 views
1

Здравствуйте, я пытаюсь сортировать набор числовых аргументов командной строки и затем отсылать их обратно в обратном числовом порядке в одной строке с пробелом между ними. У меня есть этот цикл:Сортировка по одной и той же линии Bash

for var in "[email protected]" 
do 
echo -n "$var " 
done | sort -rn 

Однако, когда я добавил -n к эху sort команда перестает работать. Я пытаюсь сделать это, не используя printf. Используя echo -n, они не сортируют и просто печатают в том порядке, в котором они были введены.

+1

По какой причине вы не хотите использовать 'printf'? AFAIK, обычно 'echo' с аргументами, не переносится. – Jite

ответ

2

sort Используется для сортировки нескольких строк текста. Используя опцию -n из echo, вы печатаете все в одной строке. Если вы хотите, чтобы вывод будет отсортирован, вы должны напечатать его в нескольких строках:

for var in "[email protected]" 
do 
    echo $var 
done | sort -rn 

Если вы хотите, чтобы результат только на одной линии, которую вы могли бы сделать:

echo $(for var in "[email protected]"; do echo $var; done | sort -rn) 
+0

'echo -n' просто добавить' \ n' после строки, имеет смысл ... – Jite

+1

echo -n * не отображает '\ n' –

+0

@Jite Это действительно немного искажено, чтобы использовать' -e', чтобы пресечь опцию -n. – zakinster

3

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

a=([email protected]) 
b=($(printf "%s\n" ${a[@]} | sort -rn)) 

printf "%s\n" ${b[@]} 
# b is reverse sorted nuemrically now 
1

man sort бы вам сказать:

sort - sort lines of text files 

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

Для того, чтобы достичь желаемого результата, вы можете сказать:

for var in "[email protected]" 
do 
    echo "$var" 
done | sort -rn | paste -sd' ' 
1

Один Хитрость заключается в том, чтобы играть с МФС:

IFS=$'\n' 
set "$*" 
IFS=$' \n' 
set $(sort -rn <<< "$*") 
echo $* 

Это та же идея, но легче читать с join():

join() { 
    IFS=$1 
    shift 
    echo "$*" 
} 

join ' ' $(join $'\n' $* | sort -nr) 
+0

Это работает. Я думаю, вы должны объяснить немного больше о том, почему это работает. Преднамеренно ли вы устанавливаете IFS на две нестандартные настройки или это второй параметр, предназначенный для восстановления значения по умолчанию? Если первое, то почему бы не просто 'IFS = $ '''; если последнее, вы опустили вкладку и лучше сохранили текущее значение и восстановили его: 'save =" $ IFS "; IFS = $ '\ n'; установить «$ *»; IFS = «$ save»; установить $ (sort -rn <<< "$ 1"); echo $ * '. Поскольку существует только один аргумент, вы можете написать '$ 1' вместо' $ * 'в' <<< 'redirect. И т. Д. –

+0

@ Джонатан, настройки «IFS» преднамеренно. Этот метод использует IFS и echo для объединения позиционных параметров с произвольным символом. Когда 'IFS' установлен в' $ '\ n'' и 'set' $ *" ', то позиционные параметры затем разделяются символами новой строки. Я не беспокоюсь о сохранении '$ IFS', поскольку он ограничен только суб-оболочкой: ' bash -c 'IFS = "xyz" && printf "$ IFS \ n"'; printf "$ IFS \ n" ' –

1

Возможно, это потому, что сортировка «ориентирована на линию», поэтому вам нужно каждое число на отдельной строке, что не имеет значения -n с эхом. Вы можете просто поместить отсортированные номера обратно в одну строку с помощью СЭД, так:

for var in "[email protected]"; 
do 
    echo "$var "; 
done | sort -rn | sed -e ':a;N;s/\n/ /;ba' 
+1

Добро пожаловать в Stack Overflow. Да, проблема в том, что 'sort' является ориентированным на линию, а' echo -n' создает одну строку. В то время как 'sed' работает, это довольно сложный вариант. –

Смежные вопросы