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

时间:2016-11-07 02:29:40

标签: linux bash shell unix sh

我正在尝试使用bash中的几个.txt文件遍历一个目录。我对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

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

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

或只是

cat /<dir_path>/*.txt | your_parser

答案 1 :(得分:2)

更大的问题是你是否真的需要将每个感兴趣的文件的内容读入一个shell变量,但为了实现这一点,你的尝试的主要问题是你有空白周围的空白}在您的变量作业中签名 ,这是不受支持的。

=这样的东西(注意contents = ...周围的空格)会让shell认为你正在执行一个名为=命令,它会失败。

因此,由于为稳健性添加了固定和双引号变量的问题,以下内容应该有效:

contents

答案 2 :(得分: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)

答案 3 :(得分:0)

例如,我们假设file1.txt包含“texta”,file2.txt包含“text b”,file3.txt包含“textc”。 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

这会在for循环中找到每个文件运行一次while循环。同样,变量赋值行可以根据需要替换为任何其他方法。