2017-04-14 56 views
3

我有一個文件哈希文件的文件名。 例如,如何在bash中使用函數?

fb7e0a4408e46fd5573ffb9e73aec021a9dcf426235c0ccfc37d2f5e09a68a23 /path/to/some/file 
237e0a4408e46fe3573f239e73aec021a9dcf426235c023fc37d2f5e09a68a12 /path/to/another/file 
... and so on... 

我需要散列轉換爲base64編碼格式。

所以我用了一個bash函數和awk的組合。

這裏是我寫的,

#!/bin/sh 
base64Encode() { 
    $1 | openssl base64 -A 
} 
awk ' { t = base64Encode $1; print t } ' file.txt 

但它似乎並沒有工作。我使用hashdeep來生成哈希列表文件,並且hashdeep不支持base64編碼的輸出。這就是我使用openssl的原因。

任何幫助或提示關於這將是偉大的!

編輯:

給出的答案工作,但我有似乎有些其他問題。

一般cat filename | openssl dgst -sha256 | openssl base64 -A給出filename文件,該文件是正確absoutely, 和輸出從cat filename | openssl dgst -sha256匹配的輸出hashdeep一個base64編碼輸出。 因此,我想到了將從上述步驟獲得的輸出管道輸出爲openssl base64 -A,base64輸出。但是,我仍然從實際結果中得到不同的值。

儘管這可能適合單獨的問題,但我仍然希望對此有所支持。

+0

您期待什麼輸出?你不需要文件名嗎? – 123

+0

@ 123我會使用文件名,但我不能使'base64'編碼工作。這只是一個演示代碼。 – Ozil

+1

awk不是shell。您不能從awk腳本調用shell函數,也不能從awk腳本調用C函數,反之亦然。在這種情況下,與僅從shell調用shell函數相比,awk腳本對你來說完全沒有任何幫助 - 是否有任何理由不這麼做? –

回答

1

只有在awk:

$ awk '{ c="echo " $1 "|openssl base64 -A" 
     c | getline r 
     print r }' file 
ZmI3ZTBhNDQwOGU0NmZkNTU3M2ZmYjllNzNhZWMwMjFhOWRjZjQyNjIzNWMwY2NmYzM3ZDJmNWUwOWE2OGEyMwo= 
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo= 

對於緊的單行版本中看到@ 123下方的評論。

...和@ EdMorton的超緊(閱讀:超級證明)版本。

+1

只能做'awk'{「echo」$ 1「| openssl base64 -A」| getline} 1'檔案' – 123

+0

@ 123當然,但它看起來很不妥,我的眼睛不得不將它分解。 –

+1

@ 123否,因爲那樣你不能用'close(c)'平息管道。 James - 記得測試getline成功並關閉管道('if((c | getline line)> 0)r = line; else r =「N/A」; close(c)')但當然awk在做在這種情況下你什麼都沒有,所以你不會真的在這麼簡單的應用中使用它,你只需要使用一個shell腳本。 –

1

因爲您特別要求如何使用函數,我將問題分爲幾個小函數。在所有(更大的)bash程序中這是一個好習慣。

的基本規則是:函數的行爲就像任何其他的命令:

  • 你可以重定向它們的輸入/輸出
  • 你可以帶參數
  • ,喜歡給他們打電話。

最好的功能就像普通的unix可執行文件一樣,從標準輸入讀取並打印到標準輸出。這可以讓你在管道中使用它們。

所以,現在重寫:

# function for create base64 - reads from stdin, writes to stdout 
base64Encode() { 
     openssl base64 -A 
} 

# function for dealing with your file 
# e.g. reads lines "hash path" and prints "base64 path" 
convert_hashes() { 
     while read -r hash path; do 
       b64=$(base64Encode <<< "$hash") 
       echo "$b64 $path" 
     done 
} 

#the "main" program 
convert_hashes < your_file.txt 

輸出

ZmI3ZTBhNDQwOGU0NmZkNTU3M2ZmYjllNzNhZWMwMjFhOWRjZjQyNjIzNWMwY2NmYzM3ZDJmNWUwOWE2OGEyMwo= /path/to/some/file 
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo= /path/to/another/file 

是的,我知道,我只想要base64沒有附加路徑。當然,您可以修改上面的convert_hashes並從輸出中刪除路徑,例如而不是echo "$b64 $path"你可以使用echo "$b64"和輸出將只是b64字符串只有 - 你失去了函數中的信息 - 哪個字符串屬於哪個路徑 - 恕我直言,不是最佳做法。因此,您可以按原樣保留該功能,並使用其他工具獲取第一列 - 並且僅在需要時纔會使用 - 例如,在「主」程序中。通過這種方式,您已經設計了一個功能,以後用於更普遍的方式

convert_hashes < your_file.txt | cut -d ' ' -f1 

輸出

ZmI3ZTBhNDQwOGU0NmZkNTU3M2ZmYjllNzNhZWMwMjFhOWRjZjQyNjIzNWMwY2NmYzM3ZDJmNWUwOWE2OGEyMwo= 
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo= 

現在想象一下,你擴展腳本,並希望不使用的文件,但輸入從另外一個程序來:讓我們用下面的get_data函數模擬這種(當然在真正的應用程序會做以外的東西,而不僅僅是cat

get_data() { 
cat <<EOF 
fb7e0a4408e46fd5573ffb9e73aec021a9dcf426235c0ccfc37d2f5e09a68a23 /path/to/some/file 
237e0a4408e46fe3573f239e73aec021a9dcf426235c023fc37d2f5e09a68a12 /path/to/another/file 
EOF 
} 

現在你可以使用的上述所有爲:

get_data | convert_hashes 

輸出將與上面相同。

當然

,你可以做一些與輸出也讓說

get_data | convert_hashes | grep another/file | cut -d ' ' -f1 
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo= 

當然,如果你有這樣的「模塊化」結構,可以輕鬆地更換任何零件,無需觸碰其它部位,比方說要用base64命令替換openssl

base64Encode() { 
     base64 
} 

而且一切都會繼續工作,沒有任何其他變化。當然,在真正的應用程序中(可能)沒有任何功能,只能調用一個程序 - 但我特別這樣做是因爲你詢問了函數。

否則,上面可以簡單的完成:

while read -r hash path; do 
    openssl base64 -A <<<"$hash" 
    echo 
    #or echo $(openssl base64 -A <<<"$hash") 
    #or printf "%s\n" $(openssl base64 -A <<<"$hash") 
done < your_file.txt 

甚至

cut -d ' ' -f1 base | xargs -I% -n1 bash -c 'echo $(openssl base64 -A <<<"%")' 

您需要echoprint因爲openssl默認情況下不打印換行符。輸出:

ZmI3ZTBhNDQwOGU0NmZkNTU3M2ZmYjllNzNhZWMwMjFhOWRjZjQyNjIzNWMwY2NmYzM3ZDJmNWUwOWE2OGEyMwo= 
MjM3ZTBhNDQwOGU0NmZlMzU3M2YyMzllNzNhZWMwMjFhOWRjZjQyNjIzNWMwMjNmYzM3ZDJmNWUwOWE2OGExMgo= 

PS:說實話,我不明白爲什麼你需要Base64編碼,有的已編碼的哈希 - 但情況因人而異。 :)

+0

感謝您提供這樣豐富的答案! – Ozil

+0

@Ozil沒有問題,享受 - 只是還不明白你想要達到什麼... – jm666