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
  • 42,970
  • 10
  • 60
  • 71
  • 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
  • 239,568
  • 38
  • 324
  • 436
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
  • 191,897
  • 31
  • 273
  • 432
  • 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
  • 761,203
  • 64
  • 569
  • 643
  • 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