Bash: creating file names according to directory names

10,755

Solution 1

If you want the filenames to literally be named name_date.txt, try this:

#!/bin/bash
for dir in $(find . -maxdepth 2 -mindepth 2 -type d)
do
    touch "$dir"/name_date.txt
done

If you want the filenames to be <name>_<date>.txt, do this instead:

#!/bin/bash
IFS=$'\n'
for dir in $(find . -maxdepth 1 ! -path . -type d)
do
    for subdir in $(find "$dir" -mindepth 1 -type d)
    do
        base_dir=$(basename $dir)
        base_subdir=$(basename $subdir)

        touch "$base_dir"/"$base_subdir"/"$base_dir"_"$base_subdir".txt
    done
done

Solution 2

From the Parent_dir:

for d in */*/; do f=${d/\//_}; touch -- "$d"/"${f::-1}.txt"; done

Note that touch will change the timestamp of any existing file.

You can do a dry-run first with replacing touch with echo:

for d in */*/; do f=${d/\//_}; echo -- "$d"/"${f::-1}.txt"; done
  • for d in */*/ lets us iterating over the directories two levels deep

  • f=${d/\//_} replaces first directory separator / with _ and save the output as variable f

  • "$d"/"${f::-1}.txt" expands to the directory name, followed by the desired filename; ${f::-1} strips off the last / from variable f

Note that, as the directory separator / is present with variable d, the / in "$d"/"${f::-1}.txt" is redundant; as almost all systems take // as single /, this should not be a problem. Alternately, you can drip /:

for d in */*/; do f=${d/\//_}; touch -- "${d}${f::-1}.txt"; done

Solution 3

find . -type d -exec sh -c '
   case ${1//[!\/]/} in
      "//" ) f=${1:2}; f=${f/\//_}; :> "$1/$f.txt" ;;
      * ) false ;;
   esac
' {} {} \; -prune

for d in */*/; do
   f=${d/\//_}
   :> "${d%?}/${f%?}.txt"
done
Share:
10,755

Related videos on Youtube

Austin
Author by

Austin

Updated on September 18, 2022

Comments

  • Austin
    Austin almost 2 years

    Say I have a directory structure that is like Parent_dir/<name>/<date>/

    How can I use a bash script placed into Parent_dir to navigate through every /<name>/<date>/ subdirectory and create a blank text file named <name>_<date>.txt within /<name>/<date>/ subdirectory?

    • Hölderlin
      Hölderlin about 7 years
      Are name and date placeholders as well?
    • Austin
      Austin about 7 years
      yes there's 20 different "name" directories (some have spaces if that matters) and 93 different "date" directories within each
    • Austin
      Austin about 7 years
      edited my post to make it a bit more clear.
    • heemayl
      heemayl about 7 years
      Where the new files would be created?
    • Austin
      Austin about 7 years
      sorry made another edit
  • buffcat
    buffcat about 7 years
    Try now - the IFS should fix it. It's a bit of a hack, but should work.
  • Austin
    Austin about 7 years
    Perfect much appreciated!
  • Austin
    Austin about 7 years
    Thanks! I'll try this out later because it looks very clean although the first post seemed to work for my needs :)
  • don_crissti
    don_crissti about 7 years
    Rakesh buddy, please add some explanation to your posts as they keep showing up in the Low Quality Post review queue due to the fact there's only code and no text (I just had to review three of them)...
  • don_crissti
    don_crissti about 7 years
    See Why is looping over find's output bad practice? Learn how to do it the right way and there won't be any need for "hacks"...