1

Similar to this question

but I want to have file name be the same name as the directory with "_info.txt" appended to it.

I have tried this

#!/bin/bash

find . -mindepth 1 -maxdepth 1 -type d | while read line; do
    touch /Users/xxx/git/xxx/$line/$line_info.txt
done

It is creating ".txt" in each subdirectory.

What am I missing ?

mindblowwn
  • 11
  • 3

6 Answers6

1

The crucial mistake is that the underscore character is a valid character for a bash variable name:

$ a=1
$ a_b=2
$ echo $a_b
2

There are several ways around this:

$ echo "$a"_b
1_b
$ echo $a'_b'
1_b
$ echo ${a}_b
1_b

As for your task, here's a fast way:

find . -mindepth 1 -maxdepth 1 -type d -printf "%p_info.txt\0" | xargs -0 touch

The find -printf prints the path of each directory, and printf's %p is unaffected by an underscore after it. Then, xargs passes the filenames as many arguments to few runs of touch, making the creation of the files much faster.

webb
  • 4,180
  • 1
  • 17
  • 26
  • From the link i guess the info.txt file should be inside the directory and not at the same level. – sjsam May 02 '16 at 03:16
  • @sjsam, i modified my answer; i'm not sure if your comment is relevant now. – webb May 04 '16 at 00:15
0

Figured it out:

#!/bin/bash

find . -mindepth 1 -maxdepth 1 -type d | while read line; do
touch /Users/xxxx/git/xxxx/$line/"$line"_info.txt
done

I think I can still do the "find ." better as I have to run in directory I want the files added to. Ideally it should be able to be run anywhere.

mindblowwn
  • 11
  • 3
0

Try this script :

#!/bin/bash
find $1 -type d | while read line
do
touch "$line/$(basename $( readlink -m $line))_info.txt"
done

Save it as, say, appendinfo and run it as

./appendinfo directory_name_which_include_symlinks

Before

ssam@udistro:~/Documents/so$ tree 36973628
36973628
`-- 36973628p1
    `-- 36973628p2
        `-- 36973628p3

3 directories, 0 files

After

ssam@udistro:~/Documents/so$ tree 36973628
36973628
|-- 36973628_info.txt
`-- 36973628p1
    |-- 36973628p1_info.txt
    `-- 36973628p2
        |-- 36973628p2_info.txt
        `-- 36973628p3
            `-- 36973628p3_info.txt

3 directories, 4 files

Note : readlink canonicalizes the path by following the symlinks. It is not required if, say, you're not going to give arguments like ..

sjsam
  • 21,411
  • 5
  • 55
  • 102
0

If you are not recursing at all, you don't need find. To loop over subdirectories, all you need is

for dir in */; do
    touch /Users/xxxx/git/xxxx/"$dir/${dir%/}_info.txt"
done

Incidentally, notice that the variable needs to be in double quotes always.

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

Try this :

find . /Users/xxx/git/xxx/ -mindepth 1 -maxdepth 1 -type d -exec bash -c 'touch ${0}/${0##*/}_info.txt' {} \;
SLePort
  • 15,211
  • 3
  • 34
  • 44
-1

You're missing the path to the folder. I think you meant to write

touch "./$folder/*/*_info.txt"

Although this still only works if you start in the right directory. You should really have written something like

touch "/foo/bar/user/$folder/*/*_info.txt"

However, your use of "*/*_info.txt" is very... questionable... to say the least. I'm no bash expert, but I don't expect it to work. Reading everything in a directory (using "find" for example, and only accepting directories) and piping that output to "touch" would be a better approach.

Eric
  • 79
  • 1
  • 3