Wednesday, August 5, 2009

Remove path from find result in Bash


Find all .sh files from current directory.

$ find . -name "*.sh"

./als.sh
./engine/a.sh
./engine/mysc.sh
./tools/new/slv.sh
./tools/instant-parse/iparse.sh

Now if we need to remove the path part from the above find command output:

$ find . -name "*.sh" -exec basename {} \;

als.sh
a.sh
mysc.sh
slv.sh
iparse.sh


Same as

$ find . -name "*.sh" | xargs -i basename {}

And using sed:

$ find . -name "*.sh" | sed 's!.*/!!'

i.e. replace all characters until last / by nothing (here ! is used as the sed delimiter instead of the usual /)

8 comments:

Shahriar's Blog said...

>>>>Find all .sh files from current directory.

$ find . -name "*.sh"

./als.sh
./engine/a.sh
./engine/mysc.sh
./tools/new/slv.sh
./tools/instant-parse/iparse.sh

Hi,
What should be the command if you want to remve all the .sh files from above output? This means, you want to remove als.sh, a.sh, mysc.sh, slv.sh and iparse.sh and you want to get output as:

./
./engine/
./engine/
./tools/new/
./tools/instant-parse/

Thanks!

Shahriar's Blog said...

$ find . -name "*.sh"
./als.sh
./engine/a.sh
./engine/mysc.sh
./tools/new/slv.sh
./tools/instant-parse/iparse.sh

Hi,
What should be the command for output (you want only the directory name with file name with *.sh)?

So the output:

./
./engine/
./engine/
./tools/new/
./tools/instant-parse/

Shahriar's Blog said...

I already wrote the right code.

Jadu Saikia said...

@Shahria's Blog:

You can use one of the following:

1)
find . -name "*.sh" -exec rm -f {} \;

2)
find . -name "*.sh" | xargs rm -f

3)
find . -name "*.sh" | while read file;
do
rm -f $file ;
done

4) for file in $(find . -name "*.sh");
do
rm -f $file ;
done

Keep in touch.

Shahriar's Blog said...

Thanks!

I usd this:

find src -name '*msgs.msg' > Msg_File_list

sed 's/[^\/]\+$//' Msg_File_list > Removal_List

then do other tasks......

Jadu Saikia said...

@Shahria's Blog:
Hey, I misunderstood your requirement. I assumed you were trying to remove the files actually.

here is a solution using awk:

$ cat file.txt
./als.sh
./engine/a.sh
./engine/mysc.sh
./tools/new/slv.sh
./tools/instant-parse/iparse.sh

$ awk 'BEGIN{FS=OFS="/"}{$NF=""}{print}' file.txt

Output:
./
./engine/
./engine/
./tools/new/
./tools/instant-parse/

Shahriar's Blog said...

Thanks!

What does it mean by:

FS=OFS="/"}{$NF=""}{

Jadu Saikia said...

@Shahria's Blog:

awk 'BEGIN{FS=OFS="/"}{$NF=""}{print}' file.txt

FS = field separator
OFS = output field separator
NF = number of fields in the current record (line)

So $NF prints the last column in a record (line)

in this case I am removing the last field by
$NF=""

Please try the following two awk one liners:

awk -F "/" '{print NF}' file.txt

awk -F "/" '{print $NF}' file.txt

Please let me know if you have any doubt/question. Thanks.

© Jadu Saikia www.UNIXCL.com