LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 07-28-2009, 08:49 AM   #1
neo2k
LQ Newbie
 
Registered: Aug 2008
Posts: 21

Rep: Reputation: 15
Question interchanging lines in a textfile in bash script


guys,

I need a steer in the right direction for this issue. it would be great if anyone of you can help me out.

i have a textfile where i want to swap the lines based on the user input.

The textfile is looks like the

#file 1 name
TB
#file 1 ID
1000
#
#file for ID1 system1
AB_12_TB_3000
#
#file for ID1 system2
BC_12_TB_3000
#file 2 name
CO
#file 2 ID
5000
#
#file for ID2 system1
AB_12_CO_3000
#
#file for ID2 system2
BC_12_CO_3000

if the user enters CO then i want CO,5000 and the files should be file 1 and the TB should be file 2. basically interchanging it and making the user entry to be on top and putting the top one to be on the placeholder of file2.here i have mentioned only 2 files, but i am dealing with more than 2 in my files.

The code i have written so far is like this. it works except the ID part.

THE FILENAME IS ROCK.IN i.e that why u see rock.in at the end.

MY QUESTION WOULD BE

1)IS THERE A MORE ROBUST AND EASIER WAY TO DO THIS.

2)MY LAST SED STATEMENT IS NOT CHANGING IT PROPERLY

Code:
#!/bin/bash


user_rock=$(grep -hi 'tb' rock.in)

val=$(grep -A 3 -m 1 -hi 'tb' rock.in)



rock1=$(sed -n -e '/file 1/ {n;p;}' rock.in)


D1=`echo $rock1 | cut -d ' ' -f3`
r_name=`echo $D1| cut -d '_' -f3`

D2=`echo $rock1 | cut -d ' ' -f2`

D3=`echo $val | cut -d ' ' -f5`
D6=`echo $val | cut -d ' ' -f3`

D4=`echo $user_rock | cut -d ' ' -f3`
u_name=`echo $D4| cut -d '_' -f3`

sed -i "s/$u_name/ch/gi" rock.in

sed -i "s/$r_name/$u_name/gi" rock.in

sed -i "s/ch/$r_name/gi" rock.in

sed -i "/file 1 ID/,/{n;p;}/s/$D2/$D3/g" rock.in

sed -i "/file $D6 ID/,/{n;p;}/s/$D3/$D2/g" rock.in


#echo $D3 $D2 

exit 0
I WOULD APPRECIATE ANY IDEAS OR SUGGESTIONS. THANKS AGAIN

Last edited by neo2k; 07-28-2009 at 10:19 AM.
 
Old 07-28-2009, 09:10 AM   #2
neo2k
LQ Newbie
 
Registered: Aug 2008
Posts: 21

Original Poster
Rep: Reputation: 15
let me know if you guys have any questions on the way i have explained the file.

let me post the desired output..
#file 1 name
CO
#file 1 ID
5000
#
#file for ID1 system1
AB_12_CO_3000
#
#file for ID1 system2
BC_12_CO_3000
#file 2 name
TB
#file 2 ID
1000
#
#file for ID2 system1
AB_12_TB_3000
#
#file for ID2 system2
BC_12_TB_3000

once the user input is CO, i move the CO and its desired files to the file1 and the old values of file 1 to where the CO was.

hope this is clear if not i can explain it again.

Last edited by neo2k; 07-28-2009 at 09:39 AM.
 
Old 07-28-2009, 10:32 AM   #3
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Sorry, I did not tried to correct your script, but I followed my logic. I assume the file has a fixed format, that is each ID field is made of exactly 10 lines:
Code:
#!/bin/bash
string=CO

D1=$(grep -B1 -A8 -wi $string rock.in)
D1_MULTI=$(grep -B1 -A8 -wi $string rock.in | sed 's/$/\\/g' | sed '$s/.$//')
D1_START=$(nl rock.in | grep -B1 -A8 -wi $string | awk 'BEGIN{getline;print $1}')
D1_END=$(nl rock.in | grep -B1 -A8 -wi $string | awk 'END{print $1}')

if [ $D1_START -ne 1 ]
then

  D2_MULTI=$(head -10 rock.in | sed 's/$/\\/g' | sed '$s/.$//')

  #
  #  Delete line numbers from D1_START to D1_END
  #
  sed -i ${D1_START},${D1_END}d rock.in

  #
  #  Insert multiple lines (D1) before first line 
  #
  sed -i "1i${D1_MULTI}" rock.in

  #
  #  Delete previous header (shifted 10 lines below)
  #
  sed -i '11,20d' rock.in

  #
  #  Add multiple lines (D2) in the original position of D1
  #
  sed -i "$((D1_START-1))a${D2_MULTI}" rock.in

  #
  #  Re-number file IDs sequentially
  #
  for i in $(seq 1 $(grep -c "#file .* name" rock.in))
  do
    sed -i "$(((i-1)*10+1))"',$s/^#file .* name$/#file '"$i name/" rock.in
    sed -i "$(((i-1)*10+1))"',$s/^#file .* ID$/#file '"$i ID/" rock.in
    sed -i "$(((i-1)*10+1))"',$s/^#file for ID.* system1$/#file for ID'"$i system1/" rock.in
    sed -i "$(((i-1)*10+1))"',$s/^#file for ID.* system2$/#file for ID'"$i system2/" rock.in
  done < <(grep "/#file . name/" rock.in)

fi
If the wanted ID is already at the head of the file, it doesn't make any modification. Just some ideas from which you can take suggestions. Feel free to ask for any doubt.
 
Old 07-28-2009, 10:55 AM   #4
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Just thought about a more simple solution: can't you just substitute the two strings, CO with TB and vice-versa?
Code:
#!/bin/bash
string=CO

D1_START=$(nl rock.in | grep -B1 -A8 -wi $string | awk 'BEGIN{getline;print $1}')
D1_END=$(nl rock.in | grep -B1 -A8 -wi $string | awk 'END{print $1}')
D2=$(sed -n '2p' rock.in)

if [ $D1_START -ne 1 ]
then
  sed -i "1,10s/${D2}/${string}/g" rock.in
  sed -i "${D1_START},${D1_END}s/${string}/${D2}/g" rock.in
fi
 
Old 07-28-2009, 11:19 AM   #5
neo2k
LQ Newbie
 
Registered: Aug 2008
Posts: 21

Original Poster
Rep: Reputation: 15
colucix,

Thanks for both of your replies. The one problem is that the files is not a fixed format file.That means there can be more than 10 lines for file1.whatever you have referred in your second solution is what i did in my original script. but yours looks lot cleaner.

i think i will modify your second solution to meet my needs for the random file and will test it and let you know.

one more question is on my original script i am trying to change the file1 ID to file 2 ID when i am trying to change TB to CO and viceversa. That i am trying to do in the last sed statement but instead its replacing all the matching numbers.

could you point out the error in the last sed statement.

Thanks again for your time. if i find a more solution for this i will post it here.
 
Old 07-28-2009, 11:48 AM   #6
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Well... it's difficult to debug your script, since the D1 and r_name variables result empty. Anyway, if you want to be sure to make just one substitution, remove the "g" modifier at the end of the "s" command.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
i am missing new lines when substituting with sed in a bash script FIRATYILDIRIM Programming 7 12-15-2008 03:07 PM
bash script to remove the blank lines in the file naveensankineni Programming 7 03-25-2008 08:34 PM
bash script that can read lines of text palceksmuk Programming 1 12-25-2005 03:49 AM
bash: read lines from a configuration script ldp Programming 2 09-23-2005 11:58 AM
Can't get lines of a file with a Bash script.. barisdemiray Programming 2 08-11-2004 12:42 PM


All times are GMT -5. The time now is 05:09 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration