Problem
In a directory there are files of the format: *-foo-bar.txt.
Example directory:
$ ls *-*
asdf-foo-bar.txt ghjk-foo-bar.txt l-foo-bar.txt tyui-foo-bar.txt
bnm-foo-bar.txt iop-foo-bar.txt qwer-foo-bar.txt zxcv-foo-bar.txt
Desired directory:
$ ls *.txt
asdf.txt bnm.txt ghjk.txt iop.txt l.txt qwer.txt tyui.txt zxcv.txt
Solution 1
The first solution that came to my mind looks somewhat like this ugly hack:
ls *-* | cut -d- -f1 | sed 's/.*/mv "\0-foo-bar.txt" "\0.txt"/' > rename.sh && sh rename.sh
The above solution creates a script, on the fly, to rename the files. This solution also tries to parse the output of ls which is not a good thing to do as per http://mywiki.wooledge.org/ParsingLs.
Solution 2
This problem can be solved more elegantly with a shell script like this:
for i in *-*
do
mv "$i" "`echo $i | cut -f1 -d-`.txt"
done
The above solution uses a loop to rename the files.
Question
Is there a way to solve this problem in a single line such that we do not have to explicitly script a loop, or generate a script, or invoke a new or the current shell (i.e. avoid sh, bash, ., etc. commands)?
Have you tried the rename command?
For example:
If you don’t have that available, I would use
find,sed, andxargs: