你好,我正在嘗試排序一組數字命令行參數,然後在相同的行上以相反的數字順序回顯它們,每行之間有一個空格。我有這樣的循環:排列在同一行Bash
for var in "[email protected]"
do
echo -n "$var "
done | sort -rn
然而,當我加入了-n
到回波sort
命令停止工作。我試圖在不使用printf
的情況下執行此操作。使用echo -n
他們不排序,只是按照他們輸入的順序打印。
你好,我正在嘗試排序一組數字命令行參數,然後在相同的行上以相反的數字順序回顯它們,每行之間有一個空格。我有這樣的循環:排列在同一行Bash
for var in "[email protected]"
do
echo -n "$var "
done | sort -rn
然而,當我加入了-n
到回波sort
命令停止工作。我試圖在不使用printf
的情況下執行此操作。使用echo -n
他們不排序,只是按照他們輸入的順序打印。
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)
你可以這樣做像這樣:
a=([email protected])
b=($(printf "%s\n" ${a[@]} | sort -rn))
printf "%s\n" ${b[@]}
# b is reverse sorted nuemrically now
man sort
會告訴你:
sort - sort lines of text files
因此,您可以在排序後將結果轉換爲所需格式。
爲了達到預期的效果,你可以說:
for var in "[email protected]"
do
echo "$var"
done | sort -rn | paste -sd' '
一招是與IFS玩:
IFS=$'\n'
set "$*"
IFS=$' \n'
set $(sort -rn <<< "$*")
echo $*
這是同樣的想法,但更容易閱讀與加入()函數:
join() {
IFS=$1
shift
echo "$*"
}
join ' ' $(join $'\n' $* | sort -nr)
這工作。不過,我認爲你應該多解釋一下爲什麼它會起作用。您是否有意將IFS設置爲兩個非標準設置,還是第二個旨在恢復默認設置的設置?如果前者,爲什麼不只是'IFS = $''';如果是後者,則省略了選項卡,並且會更好地保存當前值並將其恢復:'save =「$ IFS」; IFS = $'\ n';設置「$ *」; IFS = 「$ save」; set $(sort -rn <<<「$ 1」); echo $ *'。由於只有一個參數,你可以在'<<<''重定向中寫'$ 1'而不是'$ *'。 Etc. –
@Jonathan,這兩個'IFS'設置是故意的。該技術使用'IFS'和echo將位置參數與任意字符結合起來。當'IFS'被設置爲'$'\ n''並且'set'$ *「'被調用時,位置參數將被換行符分隔。我不打擾保存'$ IFS',因爲它只限於子shell: 'bash -c'IFS =「xyz」&& printf「$ IFS \ n」'; printf「$ IFS \ n」' –
也許這是因爲排序是「面向行的」,所以你需要在一個單獨的行上的每一個數字,這不是使用-n和echo的情況。 您可以簡單地使用sed將排序後的數字重新放在一行中,如下所示:
for var in "[email protected]";
do
echo "$var ";
done | sort -rn | sed -e ':a;N;s/\n/ /;ba'
歡迎使用堆棧溢出。是的,麻煩是因爲'sort'是面向行的,'echo -n'創建單行。雖然'sed'的作品,這是一個相當沉重的選擇。 –
您爲什麼不想使用'printf'? AFAIK,通常帶有參數的「echo」是不可移植的。 – Jite