0

I'm new to scripting concept.. I have a requirement to rename multiple files in a directory like filename.sh.x into filename.sh

First I tried to get the file names in a particular directory.. so i followed the below scripting code

for entry in PathToThedirectory/*sh.x
do
   echo $entry
done

& the above code listed down all the file names with full path..

But my expected o/p is : to get file names alone like abc.sh.x, so that I can proceed with the split string mechanism to perform rename operation easily... help me to solve this ... Thanks in advance

anishsane
  • 20,270
  • 5
  • 40
  • 73

6 Answers6

2

First approach trying to follow OP suggestions:

for i in my/path/*.py.x
do
    basename=$(basename "$i")
    mv my/path/"$basename" my/path/"${basename%.*}"
done

And maybe, you can simplify it:

for i in my/path/*.py.x
do
    mv "$i" "${i%.*}";
done

Documentation regarding this kind of operation (parameter expansion): https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

In particular:

${parameter%word} : The word is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the value of parameter with the shortest matching pattern (the ‘%’ case) or the longest matching pattern (the ‘%%’ case) deleted

So, ${i%.*} means:

  • Take $i
  • Match .* at the end of its value (. being a literal character)
  • Remove the shortest matching pattern
JoseKilo
  • 2,343
  • 1
  • 16
  • 28
  • 2
    Why "maybe"? The second solution looks much cleaner to me, doesn't require external tools and is probably faster. – Benjamin W. May 02 '16 at 05:19
  • Well, the first one sounds more like what the OP was asking for (`get file names alone`) ... but yes you are right. – JoseKilo May 02 '16 at 05:22
  • Ah, yes, but "get the file names alone" was part of an idea how to solve the problem suboptimally ;) This answer is also the only one as far as I can see that doesn't require external tools, quotes properly, doesn't break for filenames with special characters, doesn't remove the wrong stuff... good job. – Benjamin W. May 02 '16 at 05:24
  • I got it.. thank u – sivakarthik May 02 '16 at 05:28
  • The second one is very good & faster than my expectation... – sivakarthik May 02 '16 at 05:31
  • Hi , can u please explain the functionality of "${i%.*}" this? Means how it will detect the exact character in a string where we want to split? – sivakarthik May 02 '16 at 06:45
  • @sivakarthik I've updated my answer to explain it – JoseKilo May 02 '16 at 07:06
  • @JoseKilo yup i've gone through the updated answer.. It sounds good & easy to understand... thanks a lot – sivakarthik May 02 '16 at 07:46
1

Look into prename (installed together with the perl package on ubuntu). Then you can just do something like:

prename 's/\.x$//' *.sh.x
anishsane
  • 20,270
  • 5
  • 40
  • 73
Harald H
  • 58
  • 4
0

In ksh you can do this:

for $file in $(ls $path)
do
    new_file=$(basename $path/$file .x)
    mv ${path}/${file} ${path}/${new_file}   
done
Abend
  • 589
  • 4
  • 14
0

Running this rename command from the root directory should work:

rename 's/\.sh\.x$/.sh/' *.sh.x
RaviTezu
  • 3,047
  • 19
  • 26
0

This should do the trick:

for file in *.sh.x; 
do 
   mv "$file " "${file /.sh.x}"; 
done
msc
  • 33,420
  • 29
  • 119
  • 214
-1

for i in ls -la /path|grep -v ^d|awk '{print $NF}'

do

echo "basename $i" done

it will give u the base name of all files or you can try below

find /path -type f -exec basename {} \;