Mistake with sed espression is saving part of pattern
Hi all,
got a textfile with : as delimiters in between fields. e.g. 1:2:3:4:5:6 Thomas Cruise:John:David:Peter:Betty:Jane The names may or may not contain white spaces. I am required to substitute any one of these names in the file with a new one inputted by user. e.g. to change John to Johnny, David to Beckham, etc. without touching any of the other names in the same line. Just one at a time. So here's the sed expression I was trying out with: sed -i "s/<\(.:.:\)David>/$\1Beckham/" names.txt I also tried: sed -i "s/<\(.*\)David>/<\1Beckham>/" names.txt All to no avail. No error mistake, just nothing gets substituted. I am really lost and seem to be missing some crucial concept. I can only get the first field, which is Thomas Cruise, to sub. It will be very helpful if someone can also explain why there are $ and < > in the 2nd half of the sed expression ie. the new words to sub in. Please kindly assist. Thank you. Regards. |
Hey,
Quote:
Here's first of all a very _simple_ version of a replace statement: # sed 's/David/Beckham/g' names.txt to replace each occurence of David with Beckham (g extension) I'm not sure if that already serves your purpose, but you could possibly use it as a base for your work ... By the way, if it's important for you to update a specific column, maybe awk is a better choice. - Andi - |
Hi,
Sorry have to explain abit more. I might have repeated names in one line. e.g.: Thomas Peters:Thomas Cruise:Thomas Peters:Betty:Jane Hence I have to use the /( and /( characters, so that I can go specify, for example Thomas Peters in column 3 will get edited to Thomas John or something. I have to be able to exactly pinpoint which column is being edited, and the rest of the other columns cannot be edited. Only that column. I used sed because sed is able to directly edit a text file, while awk seems to require a temporary storage which is something that I am reluctant to implement. THanks for help. |
Please post a sample of the actual file, and an example of what you want the new output to be.
Go here for a really good SED tuturial: http://www.grymoire.com/Unix/ |
I think I'd reconsider the decision not to use awk. awk handles regularly delimited fields like this much better than sed.
And there are ways to avoid temporary files. You can set it inside a bash script and have the output saved to a temporary variable first, for example. |
Hi, sorry if its kind of vague.
e.g. User input - ----------------------- Line to edit: 2 Column to edit: 2 New value: Timmy Peter ----------------------- Code:
Sample file (many lines of such stuff): Thanks. |
Since you have nice lines and columns, you might be better off with AWK. The site I linked has a good tutorial.
Part of the key to this is deciding if something is to be changed based on position or content. |
Code:
Code:
$ ./shell.sh |
Hello zizou86,
I created a script that shows how you can parse/replace a name from a delimited file. You can use it to glean methods for your own script. Sorry its a little long. Cheers. What the script does : - creates a sample delimited text file of names { delimiter = : } - parses the names to numbered lines and displays to the user - requests the user choose a name (by line number), and confirms choice - prompts for a new name, shows old and new names, and confirms - changes the old name to the new name in the file - displays the sample file to the user to show the physical changes #!/bin/sh # # fx # # --- create a sample text file with data --- # # set the name of the input file where the substitution will occur ifile=tx # the header message for the user msg='This is a list of names from which one can be chosen for substitution.\ The names are numbered for reference.\ When you have found a name to be changed, remember the number and press the Q key.\n\n' # start with a fresh sample file cat /dev/null > $ifile # set the delimiter dm=':' # create a set of names to write into sample file buf= for token in 'Joe Thomas' 'Jane Thomas' 'Robert Thomas' 'Myrna Thomas' 'Edward Thomas' 'Gus Sr. Thomas' 'Bud II Thomas' do buf="$buf$token:" done # write the names to the sample file echo $buf > $ifile # show the user the list of names and ask for a choice of the one to be changed # # note how the msg is placed before the first numbered line # cat $ifile | sed 's/:/\n/g' | cat -b | sed '1s/^\(.*\)$/'"$msg"'\1/' | less # request the number from the user echo -e "\033c" echo 'Enter the number of the name to be changed and press the [ Enter ] key.' echo -e "Or just press the [ Enter ] key to exit and make no changes.\n" # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # get the choice (a line number) # read uchoice # test that the choice is a number only tst=`echo $uchoice | sed 's/[^0-9]//g'` # qualified choice if [[ $tst == $uchoice && ${#uchoice} -gt 0 ]];then # parse the old name oldname=`cat $ifile | sed 's/:/\n/g' | sed $uchoice\!d` # show the choice and get confirmation from the user echo -e "\033c" echo -e "This is your choice : $oldname\n" echo 'IF this choice is CORRECT and you want to change the name, then enter the NEW NAME and press the [ Enter ] key.' echo -e "Otherwise if this choice is NOT CORRECT then just press the [ Enter ] key and no changes will be made.\n" # get the new name read newname # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # qualified new name if [[ $newname ]];then # confirm with user echo -e "\033c" echo -e "The OLD NAME to be changed is : $oldname\n" echo -e "You chose this NEW NAME to replace the old name : $newname\n" echo 'IF this is correct then press the [ Y ] key, then the [ Enter ] key.' echo 'IF NOT correct then just press the [ Enter ] key and no changes will be made.' echo # get the users choice to proceed or not read confirmed fi # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # qualified name if [[ $newname && $confirmed ]];then # tmp file dts=`date "+%Y%m%d%H%M%S"`; tmpfile="oldversion-${dts}-${ifile}" # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # backup the original file and # replace the old name with the new name in the file # if [[ $newname ]];then cat $ifile > $tmpfile cat $tmpfile | sed 's/:'"$oldname"':/:'"$newname"':/g' > $ifile fi # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # show and tell echo -e "\033c" echo -e "The old name ($oldname) has been changed to ($newname) in file ($ifile).\n" cat $ifile else echo 'Cancelled operation, no changes were made.' fi # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # fi # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # |
Hey great thanks...
Nah long is good. Allows me to learn more =) Thank you for bothering to dig up an old thread and posting a reply. Really appreciate it. I shall go and play around with it when I have the time. Thanks alot. |
All times are GMT -5. The time now is 03:45 PM. |