Shell-Script
Bash:將 100,000 多個字元轉換為十進制格式?
我正在尋找一種快速且不佔用大量 CPU 資源的解決方案,將 100,000 多行文本轉換為十進制格式。
# random ascii string='QPWOEIRUTYALSKDJFHGZMXNCBV,./;[]75498053$#!@*&^%(*' convert () { for ((b=0; b<${#string}; b++ )) do # convert to dec, append colon character, add to array arr+=$(printf '%d,' "'${string:$b:1}"); done; # show array contents printf '%s' "${arr[@]::-1}" } time convert
以上對短線效果很好,不到一秒就完成了任務:
$ ./stackexchange.sh 81,80,87,79,69,73,82,85,84,89,65,76,83,75,68,74,70,72,71,90,77,88,78,67,66,86,44,46,47,59,91,93,55,53,52,57,56,48,53,51,36,35,33,64,42,38,94,37,40,42 real 0m0.059s user 0m0.032s sys 0m0.016s
但對於包含許多字元的文件,這不是一個可行的解決方案。下面的函式導致我的 CPU 飆升,基本上永遠不會完成任務。好吧,我在幾分鐘後按 Ctrl+c 將其停止。這是帶有修改
string
變數的相同腳本。# random ascii string="$(cat /tmp/100000-characters.txt)" convert () { for ((b=0; b<${#string}; b++ )) do arr+=$(printf '%d,' "'${string:$b:1}"); done; printf '%s' "${arr[@]::-1}" } time convert
我也嘗試了一個while循環。它設法轉換了 100,000 個字元的文件,但仍然需要很長時間才能完成。
string="$(cat /tmp/100000-characters.txt)" convert () { # iteracte through each like while read -r -n1 char; do arr+=$(printf '%d,' "'$char"); done <<< "$string" printf '%s' "${arr[@]::-3}" } time convert
是否有優雅/簡單的解決方案將大量文本文件轉換為冒號分隔的十進制值?
Perl 來救援!
perl -nE 'say join ",", map ord, split //' < file
如果您不想逐行處理輸入,則可能需要進行更多調整。
您的大部分時間都花在建構數組上,而您似乎只是為了在末尾刪除一個冒號。相反,嘗試只使用一個標誌並避免完全建構一個數組,這明顯更快:
#!/bin/bash string='QPWOEIRUTYALSKDJFHGZMXNCBV,./;[]75498053$#!@*&^%(*' convert() { local first=1 for ((b=0; b<${#string}; b++ )); do (( first )) && first=0 || printf , printf '%d' "'${string:$b:1}" done } time convert
以下是比較時間。首先,您的初始解決方案包含 1000 個字元:
real 0m0.454s user 0m0.439s sys 0m0.057s
這個解決方案有 1000 個字元:
real 0m0.148s user 0m0.147s sys 0m0.001s
這與僅使用內置函式在 bash 中的速度差不多。如果可以的話,我敦促您使用更好的工具來處理這個問題,比如上面的 perl。