【问题标题】:Bash for loop pull text from file recursivelyBash for loop 递归地从文件中提取文本
【发布时间】:2015-08-07 18:00:36
【问题描述】:

我在编写 Bash for 循环脚本时遇到问题,该脚本可以提取父目录下许多子目录共有的特定文件的内容。

目录结构:

/Parent/child/grand_child/great_grand_child/file

其中有许多子文件夹、孙文件夹和曾孙文件夹。

我希望我的脚本执行(在伪代码中):

对于每个 grand_child 文件夹,在每个子文件夹中:

  1. 只搜索一个 great_grand_child 文件夹
  2. 找到名为0001.txt的文件
  3. 将 0001.txt 第 10 行的文本打印到输出文件中
  4. 在输出文件的下一列中,打印提取文本的文件的完整目录路径。

到目前为止我的脚本:

for i in /Parent/**; do
if [ -d "$i" ]; then
echo "$i"
fi
done

我可以帮助设计这个脚本吗? 到目前为止,这为我提供了每个 grand_child 文件夹的路径,但我不知道如何仅隔离一个 great_grand_child 文件夹,然后在 great_grand_child 文件夹内的 0001.txt 文件的第 10 行中询问文本。

【问题讨论】:

  • 每个孙文件夹是否只有一个0001.txt 文件,或者在不同的曾孙文件夹中是否可以有多个这样的文件?如果有很多,使用哪一个有关系吗?是否有任何文件夹名称包含空格或其他尴尬字符?另外,父文件夹是/Parent 还是./Parent(又名Parent)?你在问题中都提到了,所以不清楚。
  • 好问题。 0001.txt 位于每个 GREAT_grand-child 文件夹中,因此任何 grand_child 文件夹中都有许多 0001.txt(每个 great_grand_child 一个)。不过,使用哪个 0001.txt 并不重要 - 对于每个 grand_child 文件夹,它们在第 10 行都有相同的数据。除了数字、文本和下划线字符“_”之外,文件夹名称不包含空格或任何内容

标签: bash for-loop


【解决方案1】:
# For every grandchild directory like Parent/Child/Grandchild
for grandchild in Parent/*/*
do
   # Look for a file like $grandchild/Greatgrandchild/0001.txt
   for file in "$grandchild/"*/0001.txt
   do
     # If there is no such file, just skip this Grandchild directory.
     if [ ! -f "$file" ]
     then
       echo "Skipping $grandchild, no 0001.txt files" >&2
       continue
     fi

     # Otherwise print the 10th line and the file that it came from.
     awk 'FNR == 10 { print $0, FILENAME }' "$file"

     # Don't look at any more 0001.txt files in this Grandchild directory,
     # we only care about one of them.
     break
   done
done

【讨论】:

  • 这很好 - 但是对于每个“孙子”文件夹的名称略有不同这一事实我能做些什么呢?我们可以在这里使用变量而不是“孙子”吗?
  • grandchild 在这里是一个变量,它是外部 for 循环的迭代变量。还是我误会了你?
  • 我喜欢 Jonathan Leffler 的回答中的 awk 行,所以我更新了我的回答。不过,我更喜欢我的显式循环;乔纳森的排序非常聪明,但对我的口味来说有点晦涩难懂,而且这种行为很难修改(例如,对于我添加的“跳过”消息)。
  • 是的,对不起,我误解了你的代码——作为一个变量,它工作得很好。到处投票!
【解决方案2】:

鉴于名称是理智的(没有空格或其他尴尬的字符),那么我可能会选择:

find /Parent -name '0001.txt' |
sort -t / -k1,1 -k2,2 -k3,3 -u |
xargs awk 'FNR == 10 { print $0, FILENAME }' > output.file

/Parent 下找到名为0001.txt 的文件。对列表进行排序,以便每个 /Parent/Child/Grandchild 仅包含一个条目。根据需要经常运行awk,打印每个文件的第 10 行以及文件名。捕获output.file 中的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多