0

I have a txt file contains many strings(every string lies in a line). A typical string has this shape:

sno_Int-INT1_Exp-INT2_INT3.fits.fz_ovsc_rms_D4_D5_D6_D7_D8_D9

In the above string, "INT1", "INT2" and "INT3" are all integer types and their values might variant for each string in the text file, "D4 - 9" are double type(not fixed value also).

What I need to do is to change the above string to a new string like :

INT3_ovsc_rms_D4_D5_D6_D7_D8_D9

Can anybody tell me how to do it ?

Thanks!

user2740039
  • 105
  • 6

4 Answers4

1
#!/bin/bash

input=$1
left=${input%%.*}
right=${input#*.fz_}
int3=${left##*_}
output=${int3}_${right}

echo "${output}"

.

$ ./foo.sh sno_Int-INT1_Exp-INT2_INT3.fits.fz_ovsc_rms_D4_D5_D6_D7_D8_D9
INT3_ovsc_rms_D4_D5_D6_D7_D8_D9

$ ./foo.sh sno_Int-300_Exp-1000_1051.fits.fz_ovsc_rms_10.6_2.35_53.2_0_5.92_2.14
1051_ovsc_rms_10.6_2.35_53.2_0_5.92_2.14

Depending on your real input this might break horribly, though.

Adrian Frühwirth
  • 39,348
  • 9
  • 57
  • 69
  • 1
    "Depending on your real input this might break horribly" applies to most Bash seen in the wild.... – John Zwinck Mar 05 '14 at 13:08
  • @JohnZwinck Agreed, but one *can* write idiomatic and "beautiful" bash with proper error handling. It just doesn't happen very often ... – Adrian Frühwirth Mar 05 '14 at 13:10
  • @JohnZwinck, Thanks a lot for your contribution ! I like your solution not only it solved my asking but your code is very intuitive for me. Merci, :-) . – user2740039 Mar 05 '14 at 13:25
0

If you really want to do this in pure Bash, you'll need to split the string by setting IFS and then using read with a "here string". For details, see here: How do I split a string on a delimiter in Bash?

You will probably need to split it multiple times--once by underscore and then by dash, I guess.

Community
  • 1
  • 1
John Zwinck
  • 223,042
  • 33
  • 293
  • 407
0

If you don't mind awk:

echo sno_Int-INT1_Exp-INT2_INT3.fits.fz_ovsc_rms_D4_D5_D6_D7_D8_D9 | awk -F_ 'BEGIN{OFS="_"}{sub(/.fits.fz/,"",$4);print $4,$5,$6,$7,$8,$9,$10,$11,$12}'

INT3_ovsc_rms_D4_D5_D6_D7_D8_D9

Mark Setchell
  • 169,892
  • 24
  • 238
  • 370
  • Hi, Mark, thanks for your post. Your code run smoothly on my machine either. Unfortunately, I have issued the green icon of answer to somebody else... Thanks again ! – user2740039 Mar 05 '14 at 13:45
0

This awk should work:

s='1000_1051.fits.fz_ovsc_rms_10.6_2.35_53.2_0_5.92_2.14'
awk -F'[_.]' 'NR==1{i3=$2;next} {printf "%s%s%s", i3, RS, $0}' RS='_ovsc_rms' <<< "$s"
1051_ovsc_rms_10.6_2.35_53.2_0_5.92_2.14
anubhava
  • 713,503
  • 59
  • 514
  • 593
  • your code is cool. However, on my machine, I need to change the `$2` in the `{i3=$2}` to `$4` to get the same as yours(and I expected). Otherwise, what I obtained on my machine is : `Int-300_ovsc_rms_10.6_2.35_53.2_0_5.92_2.14` . – user2740039 Mar 05 '14 at 13:43