4

I have a lot of files in a directory that are named as follows ID_OTHER_STUFF.txt I'd like to rename them all to ID.txt. This isn't a duplicate because I don't know how to specify this pattern.

closed as unclear what you're asking by jasonwryan, slm, Anthon, Gilles, Hauke Laging Feb 25 '14 at 0:39

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • You can't rename them all to the same name in the same directory - you would have to move them all to different directories. – Graeme Feb 24 '14 at 19:28
  • moving them all to a different directory is fine, thanks – Walrus the Cat Feb 24 '14 at 19:29
  • This also appears to be a duplicate: unix.stackexchange.com/questions/24761/… – slm Feb 24 '14 at 21:02
  • Can you please give sample input/output for your command? – rahmu Feb 24 '14 at 22:43
  • 1
    possible duplicate of Batch renaming files – Gilles Feb 24 '14 at 23:47
13

Using the perl script prename, which is symlinked to rename on Debian based distros.

rename -n 's/^([^_]*)_.*/$1.txt/' *_*.txt

Remove the -n once you are sure it does what you want.

  • BTW obviously the ID part is a stand-in for the number. Rather than putting them in different directories according to ID, could we put them all in one directory, but the files just named ID? This answer is very good thank you. – Walrus the Cat Feb 24 '14 at 19:46
  • @Walrus, should do the job now, after a quick perl vs regex learning session for me. – Graeme Feb 24 '14 at 19:55
  • 2
    Becareful w/ the rename command there's the Perl script version (Debian/Ubuntu) and an actual executable (Red Hat distros). unix.stackexchange.com/questions/24761/…. – slm Feb 24 '14 at 21:03
2

You want to use your shell's parameter expansion to manipulate the name, like this:

for file in *.txt
do
  mv $file ${file/_*/}.txt
done

E.g.:

$ ls -1
1_foo_bar.txt
2_foo_bar.txt
$ for file in *.txt
for> do
for> mv $file ${file/_*/}.txt
for> done
$ ls -1
1.txt
2.txt

Look up Parameter Expansion in your shell's man page for more details about ${name/pattern/repl} usage.

1

Suppose your files are:

1_other_stuff.txt 2_other_stuff.txt 3_other_stuff.txt

You could do:

$ seq 1 3 | xargs -I ID mv ID_other_stuff.txt ID.txt
  • Wont work, mv only takes more that 2 arguments when the last one is a directory. Then it puts the files in that directory. Using mv requires one run per file. You can do this in a loop or use rename which is the standard tool for doing this kind of thing. – Graeme Feb 24 '14 at 20:12
  • I am giving two args to mv here. – sandyp Feb 24 '14 at 20:22
  • Apologies, my bad. – Graeme Feb 24 '14 at 20:30
0

You want to mv them in a loop, mini bash script, there are several variations. in this Question Batch renaming files.

  • I'm looking for a line of code that turns that particular pattern into the other specified pattern, thanks. – Walrus the Cat Feb 24 '14 at 19:44
  • all of the answers in that post can be written on one line, and contain the fundamental principles behind both of the other two answers, given to your question here. – X Tian Feb 24 '14 at 19:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.