如何遍历目录中的文件,然后将它们读入bash中的字符串变量

问题描述:

我想通过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 = $(

+0

我把这个放在顶部#!/ bin/bash否则我将如何确定它的bash而不是sh。文件名被保存为.sh –

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

或只是

cat /<dir_path>/*.txt | your_parser 

你可以做类似下面,使用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

例如起见,我们假设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

更大的问题是你是否真的需要阅读的兴趣变为一个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

昨天晚上我终于意识到这一点,但感谢您的帮助 –