Issue
I have some files which I would like to rename. The filenames look like below:
C18-02B-NEB-sktrim_1-20000000.fq
C18-02B-NEB-sktrim_1-30000000.fq
C18-02B-NEB-sktrim_1-50000000.fq
C18-02B-NEB-sktrim_2-20000000.fq
C18-02B-NEB-sktrim_2-30000000.fq
...
I would like to reposition the _digit
part to before .fq
like so.
C18-02B-NEB-sktrim-20000000_1.fq
C18-02B-NEB-sktrim-30000000_1.fq
C18-02B-NEB-sktrim-50000000_1.fq
C18-02B-NEB-sktrim-20000000_2.fq
C18-02B-NEB-sktrim-30000000_2.fq
...
I am able to capture my substring of interest as such:
find * | egrep -o '_[0-9]'
_1
_1
_1
_2
_2
I could also remove the substring from the string as such:
find * | sed 's/_[0-9]//'
C18-02B-NEB-sktrim-20000000.fq
C18-02B-NEB-sktrim-30000000.fq
C18-02B-NEB-sktrim-50000000.fq
C18-02B-NEB-sktrim-20000000.fq
but I am not sure how to move it over to the new position and then rename the files.
Solution
This should do it:
find . -name '*.fq' -exec sh -c 'mv "$0" "$(echo "$0" |sed "s/^\(.*\)\(_[0-9]\)\(.*\)\.fq$/\1\3\2.fq/")"' {} \;
sed
part:
sed "s/^\(.*\)\(_[0-9]\)\(.*\)\.fq$/\1\3\2.fq/"
Explanation:
find . -name '*.fq'
searches for the glob pattern *.fq
and then the -exec
option executes a mv
command per each file found.
The sh -c 'mv "$0" "$var"' {}
construct is just a mv
command with two arguments and $0
is substituted with {}
which is the filename found by find
If file renaming is all you want, better use tools that are exclusively for file renaming though. rename is a pretty popular tool to do this kind of stuff, but I got my own tool: [rnm][1].
With rnm, you can do:
rnm -rs '/^(.*)(_\d)(.*)\.fq$/\1\3\2.fq/' *.fq
Or using the exact same regex like the BRE support was dropped in favor of PCRE2.sed
command (i.e BRE):
Answered By - Jahid Answer Checked By - Marilyn (WPSolving Volunteer)