2017-09-18 50 views
2

如果Unix/Linux命令從標準輸入接受其輸入數據並在標準輸出上產生其輸出(結果)稱爲過濾器。使用bash編寫Unix過濾器

微不足道的過濾器是cat。它只是將標準輸入複製到標準輸出,不做任何修改。

如何在bash中實現cat? (忽略該命令獲取命令行參數的情況下)

我想出了

#! /bin/bash 

while IFS="" read -r line 
do 
    echo -E "$line" 
done 

這似乎只要它們不爲空在大多數情況下工作,也包含一些二進制字節的文本文件字節。但是,如果最後一行不以換行符結尾,則會從輸出中丟失。

這怎麼解決?

我幾乎肯定這個答案以前一定有答案,但是我的搜索技能似乎不夠好。

顯然我不想在bash中重新實現cat:由於空字節問題,它無法工作。但我想擴展基本循環來對文本文件的某些行進行一些自定義處理。但是,我們都看到了沒有最後一行的文本文件,所以我寧願如果可以處理這種情況。

+1

你可能更好的是在管道中鏈接現有的過濾器(比如'sed'和'awk'),而不是試圖在bash中實現這樣的東西。 – larsks

+0

[在bash中從txt文件讀取行的可能的副本](https://stackoverflow.com/questions/22897354/read-lines-from-a-txt-file-in-bash) – bfontaine

+1

它不適用於包含空字節的二進制文件;一個shell變量根本不能存儲空字節。 – chepner

回答

3

假設您不需要使用任意二進制文件(因爲shell無法將空字節存儲在變量中),您可以通過檢查line是否爲空一次來處理未被換行符終止的文件循環退出。

while IFS= read -r line; do 
    printf '%s\n' "$line" 
done 
if [ -n "$line" ]; then 
    printf '%s' "$line" 
fi 

循環,我們輸出read扒掉換行符。在最後的if中,我們不輸出換行符,因爲如果while循環讀取的最後一行以1結尾,則$line將爲空。