-2

I have got a directory with files in which some of then end with an underscore.

I would like to test each file to see if it ends with an underscore and then strip off the underscore.

I am currently running the following code:

for file in *;do
   echo $file;
   if [[  "${file:$length:1}" == "_"   ]];then 
       mv $file  $(echo $file | sed "s/.$//g");
   fi
done

But it does not seem to be renaming the files with underscore. For example if i have a file called all_indoors_ I expect it to give me all_indoors.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
kartoza-geek
  • 341
  • 1
  • 6
  • 20

4 Answers4

1

You could use built-in string substitution:

for file in *_; do
    mv "$file" "${file%_}"
done    
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
1

Just use a regex to check the string:

for file in *
do
   [[ $file =~ "_$" ]] && echo mv "$file" "${file%%_}"
done

Once you are sure it works as intended, remove the echo so that the mv command executes!


It may even be cleaner to use *_ so that the for will just loop over the files with a name ending with _, as hek2mgl suggests in comments.

for file in *_
do
   echo mv "$file" "${file%%_}"
done
Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
0

You can use which will be recursive:

while read f; do 
  mv "$f" "${f:0:-1}"; # Remove last character from $f
done < <(find . -type f -name '*_')
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • This would break if there are newlines in the file names. I suggest to loop over the glob instead of using find here. – hek2mgl Dec 28 '15 at 12:11
0

Although not a pure bash approach, you can use rename.ul (written by Larry Wall, the person behind perl). Rename is not part of the default linux environment, but is part of util-linux.

You use rename with:

rename perlexpr files

(some flags ommitted).

So you could use:

rename 's/_$//' *

if you want to remove all characters including and after the underscore.

As @hek2mgl points out, there are multiple rename commands (see here), so first test if you have picked the right one.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • The `rename` command from util-linux is *not* capable of perl regular expressions! (I also needed to realize that... ;) ) – hek2mgl Dec 28 '15 at 12:13
  • @hek2mgl: then why does the documentation specifies so? – Willem Van Onsem Dec 28 '15 at 12:20
  • If your `man rename` says so, it is not from `util-linux`. What does `rename -V` give you? `rename from util-linux 2.26.2` ? I guess you are referring to http://search.cpan.org/dist/rename/ . Nice tool! But unfortunately not part of `util-linux`. – hek2mgl Dec 28 '15 at 12:23
  • @hek2mgl: only `Usage: rename [-v] [-n] [-f] perlexpr [filenames]`. Perhaps I've installed two versions of `rename` fighting with each other... – Willem Van Onsem Dec 28 '15 at 12:25
  • 1
    To complete the confusion, there also a BSD version available! :) `rename` is a nice tool, but unfortunately it is not portable so far. – hek2mgl Dec 28 '15 at 12:26
  • 1
    @hek2mgl: well let's agree that in order to remove an underscore, one does not niet *Perlish* powers. (Furthermore I went to FOSDEM last year, and Larry Wall said in his talk that the new Perl regexes would have less representation power, simply because they tend to be error-prone). – Willem Van Onsem Dec 28 '15 at 12:28
  • 1
    Well, but `rename` from util-linux doesn't support regular expressions at all. It supports only fixed strings. It's really pretty basic. – hek2mgl Dec 28 '15 at 12:36
  • @hek2mgl: I've updated the answer with a less ambiguous reference to `rename`. – Willem Van Onsem Dec 28 '15 at 15:58
  • 1
    If you also remove the sentence that says that Larry Wall's version of `rename` belongs to `util-linux` I'm fine with it. :) – hek2mgl Dec 28 '15 at 16:18