6

I have a list of files like this:

wgEncodeCaltechRnaSeqGm12878R1x75dFastqRep1.fastq.trim.tags.sam
wgEncodeCaltechRnaSeqGm12878R1x75dFastqRep2.fastq.trim.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd1Rep1.fastq.trim00.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd1Rep1.fastq.trim01.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd1Rep1.fastq.trim02.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd1Rep2.fastq.trim00.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd1Rep2.fastq.trim01.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd1Rep2.fastq.trim02.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd2Rep1.fastq.trim00.tags.sam
wgEncodeCshlLongRnaSeqGm12878CellPapFastqRd2Rep1.fastq.trim01.tags.sam

I want to remove the Rd1, Rd2 and .sam stings from their file names. With the following bash script, I can remove the Rd1, Rd2 and .sam strings using two commands....

for i in $(ls)

do

echo "${i/Rd?/}"
echo "${i/.sam/}"

done

But I want to know how to do the two substitutions in one step Do you know how to do it?

Thanks for your time!

2
  • use for i in * not for i in $(ls) -- the first form will work properly for files with spaces in the name, the second will split those names. Commented Jun 15, 2012 at 21:30
  • I didn't knew it, but I don't have files with spaces.. Commented Jun 20, 2012 at 5:05

2 Answers 2

9

You can use extended patterns to do it all in bash.

shopt -s extglob
echo ${i//@(Rd?|.sam)}

Here's the breakdown:

  1. Use // to replace all occurrences of the pattern, not just the first.
  2. @(Rd?|.sam) is an extended pattern, which matches either Rd? or .sam. The pipe separates the two sub-patterns.

Technically, you'd like to be able to avoid removing ".sam" from the middle of the word, but it looks like this is safe for your use case.

Sign up to request clarification or add additional context in comments.

2 Comments

shopt is the general bash command for manipulating shell options. The -s flag indicates that the named option that follows is to be set. You can turn off extended pattern matching by issuing shopt -u extglob after you are done using them.
I haven't found a way. According to the bash man page, ${i/%.sam} would work, but that can't be combined with the extended patterns. ${i//@(Rd?|%.sam)} didn't work for me.
4

Of course we know!

for i in *
do
   echo $i | sed 's/Rd.//;s/\.sam$//'
done

And when you want rename these files:

for i in *
do
   mv "$i" "$(echo $i | sed 's/Rd.//;s/\.sam$//')"
done

3 Comments

I don't want to rename the files, but with "$(echo $i | sed 's/Rd.//;s/\.sam$//')" I can do what I want! Thanks!!
@IgorChubin Green... my preecious!!
with bash, you can use a here-string instead of echo $i: $(sed '...' <<< "$i")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.