Home > Blockchain >  Iterate over files in a subfolder
Iterate over files in a subfolder

Time:01-21

new here, learning bash for first time. I'm trying to iterate over files named "list.txt" placed in subfolders, manipulate and create a new files, under the same subfolder. The nest could be like this: inventory/product_names1/list.txt inventory/product_names2/list.txt As product_names is completly random, I would like to iterate over all list.txt files with unix cms like sed/grep/cut and create a new file, under the same random product_names folders.

for f in $( find . -name 'list.txt'); do for list in $f; do cat $f | cut -d']' -f2- > "$f/new_file.txt" ; done ; done

I can access files into the nest using find command. How can I redirect output in the right subfolder if the product_names is random?

inventory/product_names1/list.txt inventory/product_names1/new_file.txt inventory/product_names2/list.txt inventory/product_names2/new_file.txt

This script is intended to work in the root folder, pointing and working with entime path "inventory". $f access to inventory/product_names1/list.txt but I need the output in inventory/product_names1. How can I redirect correctly if I don't have the right value/variable?

CodePudding user response:

You can either use parameter expansion to remove the file name from the path, or you can iterate over all the directories and only work on them if they contain the list.txt file.

#!/bin/bash
for list in inventory/*/list.txt ; do
    new=${list%/*}/new_list.txt
    echo "$list" "$new"
done

# OR

for dir in inventory/* ; do
    if [[ -f $dir/list.txt ]] ; then
        echo "$dir"/list.txt "$dir"/new_list.txt
    fi
done

CodePudding user response:

find can not only find files but also execute commands when a file is found:

find . -type f -name 'list.txt' -execdir sh -c 'cut -d"]" -f2 list.txt > new_file.txt' \;

Explanations:

  • -type f condition added to skip directories named list.txt. If some of your list.txt files can be symbolic links and you want to consider them too, use -type f,l with GNU find. With other find you may need to use \(-type f -o -type l\).

  • -execdir runs the command in the directory where the file was found.

  • By default find does not print when -execdir is used. If you need it add the -print command:

    find . -type f -name 'list.txt' -execdir sh -c 'cut -d"]" -f2 list.txt > new_file.txt' \; -print
    
  • Related