2016-11-07 38 views
0

我想通過bash中的幾個.txt文件循環目錄。我對bash的使用經驗很少,但我需要使用它,因爲一旦獲得每個文件的內容,我就可以運行其他命令。我 要做到這一點:如何遍歷目錄中的文件,然後將它們讀入bash中的字符串變量

for file in <directory>; do 
    read its contents 
    do something with the contents 
done 

我發現,閱讀你可以用一個文件來執行這個文件,如果我硬編碼的文件名:

contents = $(<filename.txt) 

,並遍歷所有文件一個目錄我這樣做:

for file in dir; do 

done 

我想能夠遍歷所有文件,並用循環中的文件變量讀取它們。提前

for file in dir; do 
    contents = $(<$file) 
done 

for file in dir; do 
    contents = $(<"$file") 
done 

for file in dir; do 
    contents = $(<${file##*/}) 
done 

for file in dir; do 
    contents = $(<"${file##*/}") 
done 

for file in dir; do 
    contents = $(<$(basename "$file")) 
done 

for file in dir; do 
    filename = $(basename "$file") 
    contents = $(<$filename) 
done 

for file in dir; do 
    filename = "${file##*/}" 
    contents = $(<$filename) 
done 

感謝您的幫助: 但環沒有這些,在裏面工作(我已經試過的這些組合以及)。

+0

'用於DIR/* txt文件;做回聲「顯示$文件......」;內容= $(< 「$文件」);回聲「$內容」;完成' – anubhava

+0

我得到的命令未找到 contents = $(<「$ file」) –

+0

我把這個放在頂部#!/ bin/bash否則我將如何確定它的bash而不是sh。文件名被保存爲.sh –

回答

2
find <dir_path> -iname '*.txt' -exec cat {} + | your_parser 

或只是

cat /<dir_path>/*.txt | your_parser 
1

你可以做類似下面,使用process substitution <()

#!/bin/bash 

while IFS= read -r -d '' file 
do 
    # Your other actions on the files go here. The `-print0` option in 
    # find command helps identify all zip files even with special characters 
    # in them. 
    # The bash variable "$file" holds the zip file name which you an use in 

    printf "%s\n%s\n" "Contents of $file:-" "$(<file)" 

done < <(find directory/ -name "*.txt" -type f -print0) 
+1

這是一個強大的解決方案,但是它遍歷指定目錄的整個_subtree_,而OP自己的嘗試只關注包含在目標中的'* .txt'文件_directly_ DIR。 – mklement0

+0

@ mklement0:感謝您的敏銳觀察,或許''find'命令中的'-maxdepth 1'選項應該修復它? – Inian

+0

是的,這將修復它,但是,在這種簡單的情況下,對於目錄中的文件/ * .txt;做......是更簡單,更有效的解決方案。 – mklement0

0

例如起見,我們假設FILE1.TXT包含 「TEXTA」,文件2。 txt包含「文本b」,而file3.txt包含「文本」。 file2.txt中的文本包含一個空格。

-

如果文件是單行文件,或你,否則也不需要在每一行獨立工作,那麼你的for循環是非常完整。

for file in dir/*; do 
    contents="$contents $(<"$file")" 
done 

但是,這會產生一個單行,每個文件條目以空格分隔。根據稍後如何使用該變量,這可能會導致問題。從文件中的空間和每個條目周圍的空間是不加區分

#Value of $contents: 
texta text b textc 

可以代替使用拆分在新行中的每個文件文本;

contents="$contents\n$(<"$file")" 

#Value of $contents: 
texta 
text b 
textc 

但是,如果您的文本文件本身包含多行,則會發生同樣的問題。

您也可以將每個文件的文本拆分爲數組中的單獨索引。

contents+=("$(<"$file")") 

對於數組,每個條目可以用$ {contents [$ i]}引用,其中$ i是索引號。

#Value of ${contents[0]} 
texta 
#Value of ${contents[1]} 
text b 
#Value of ${contents[2]} 
textc 
#Value of $(contents[*]} is all indexes. Listed values are automatically separated by a space. 
texta text b textc 

你可以,當然,也做不分離,

contents="$contents$(<"$file")" 

#Value of $contents: 
textatext btextc 

-

這一切都這樣說,如果你需要按行文件分割,每行每個文件分開,你可以用一個嵌入的while循環來做到這一點。

for file in dir; do 
    while read line; do 
     contents="$contents $(<"$line")" 
    done <$file 
done 

這對while循環中的每個文件運行while循環一次。同樣,變量賦值行可以根據需要用任何其他方法替換。

+0

我不認爲OP正在尋找在變量中累積_multiple_文件的內容。 – mklement0

2

更大的問題是你是否真的需要閱讀的興趣變爲一個shell變量的每個文件的內容,但只是實現這一目標,你嘗試的首要問題是,你必須圍繞=標誌空白在您的變量分配中,不支持。

喜歡的東西contents = ...(注意周圍=空格),會使外殼覺得你執行一個命令名爲contents,這將失敗。

因此,這一問題固定和的添加了魯棒性變量雙引號,下面應該工作:

dir='.' # sample target dir 

for file in "$dir"/*.txt; do 
    contents=$(<"$file") # read contents of file $file 
    # ... work with "$contents" 
done 
+1

昨天晚上我終於意識到這一點,但感謝您的幫助 –

相關問題