2013-10-09 76 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用於對多行文本進行排序。使用echo的選項-n,您可以將所有內容打印在一行中。 如果你想輸出進行排序,你必須打印在多行:

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玩:

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

這是同樣的想法,但更容易閱讀與加入()函數:

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

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

這工作。不過,我認爲你應該多解釋一下爲什麼它會起作用。您是否有意將IFS設置爲兩個非標準設置,還是第二個旨在恢復默認設置的設置?如果前者,爲什麼不只是'IFS = $''';如果是後者,則省略了選項卡,並且會更好地保存當前值並將其恢復:'save =「$ IFS」; IFS = $'\ n';設置「$ *」; IFS = 「$ save」; set $(sort -rn <<<「$ 1」); echo $ *'。由於只有一個參數,你可以在'<<<''重定向中寫'$ 1'而不是'$ *'。 Etc. –

+0

@Jonathan,這兩個'IFS'設置是故意的。該技術使用'IFS'和echo將位置參數與任意字符結合起來。當'IFS'被設置爲'$'\ n''並且'set'$ *「'被調用時,位置參數將被換行符分隔。我不打擾保存'$ IFS',因爲它只限於子shell: 'bash -c'IFS =「xyz」&& printf「$ IFS \ n」'; printf「$ IFS \ n」' –

1

也許這是因爲排序是「面向行的」,所以你需要在一個單獨的行上的每一個數字,這不是使用-n和echo的情況。 您可以簡單地使用sed將排序後的數字重新放在一行中,如下所示:

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

歡迎使用堆棧溢出。是的,麻煩是因爲'sort'是面向行的,'echo -n'創建單行。雖然'sed'的作品,這是一個相當沉重的選擇。 –