LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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 03-19-2013, 10:43 AM   #1
casperdaghost
Member
 
Registered: Aug 2009
Posts: 349

Rep: Reputation: 16
bash array substitute the value of nth element


this is the string i want to change :

random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper cap|N||N|C|0|0000994500|S|0000115500


I named the script foobaz. It greps out a stock called random, and breaks down the pipe delimited string. The only value that i need replaced is the 27th value, or third to last element of this string with value of $2. the stock name is going to be $1 and the price will be $2.
I need this price replaced and a new string printed out.

Code:
 $  /tmp/foobaz random 999999999
random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper cap|N||N|C|0|0000994500|S|0000115500

waljoh@carpcoreinit03 master $


#!/bin/bash

stocks=$(egrep "^$1" /data/casper/stocks.txt)
echo "$stocks"


IFS='|' read -ra ADDR <<< "$stocks"

for i in "${ADDR[@]}";
do
    sed -e 's/$2/"${ADDR[27]}"/g'
    echo ${ADDR[@]}
    done

Last edited by casperdaghost; 03-19-2013 at 01:45 PM.
 
Old 03-19-2013, 11:34 AM   #2
rigor
Member
 
Registered: Sep 2011
Posts: 214

Rep: Reputation: Disabled
I'm not exactly sure what you are trying to represent here. But you can just assign a value to an array element directly.
 
Old 03-19-2013, 11:36 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,256

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
To say I am confused is an understatement.

Firstly, I think you have been using the forum long enough to know that you use code tags when displaying data or code.

Is the script supposed to be in foobaz?

Is the word 'random' a string?

What does the original data set look like? From your current output that does not contain '999999999', is this good or bad? Did the substitution work?

Lastly, in the code, what are you running sed against? I see no file no string???
 
Old 03-19-2013, 02:24 PM   #4
casperdaghost
Member
 
Registered: Aug 2009
Posts: 349

Original Poster
Rep: Reputation: 16
sorry guys - I am at work and had to do this on the sly
this is the data set :
random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper cap|N||N|C|0|0000994500|S|0000115500

this is the only part of the string that i need to replace : 0000994500 - all the other values need to stay the same.
if I just echo out the array it lines up nicely.
Code:
#!/bin/bash
stocks=$(egrep "^$1" /data/casper/stocks.txt)
echo "$stocks"


IFS='|' read -ra ADDR <<< "$stocks"

for i in "${ADDR[@]}";
do
    
    echo $i
    done
but again , all i need to do is change the 27th value in the pipe delimited string.
 
Old 03-19-2013, 02:56 PM   #5
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
Replace with what and how many times? Can't you simply do it like this:
Code:
~$ sed -e 's/0000994500/<string>/g'
OR
~$ awk 'BEGIN{FS="|"}; {gsub(/0000994500/,"<string>",$27); print $0}' infile.txt
OR
~$ echo "random|L|.....|0000994500|S|0000115500" | awk 'BEGIN{FS="|"}; {gsub(/0000994500/,"<string>",$27); print $0}'
Even you can:
Code:
~$ awk -v val=${ADDR[27]} 'BEGIN{FS="|"}; {gsub(/val/,"<string>",$27); print $0}' infile.txt

Last edited by shivaa; 03-19-2013 at 10:52 PM. Reason: Code added
 
Old 03-19-2013, 08:12 PM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.8, Centos 5.10
Posts: 17,241

Rep: Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325Reputation: 2325
Hers' one using cut
Code:
t='random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper cap|N||N|C|0|0000994500|S|0000115500'

# Grab front of rec
f=$(echo $t|cut -d'|' -f1-26)
#random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper cap|N||N|C|0

# grab end of rec
e=$(echo $t|cut -d'|' -f28-)
#S|0000115500

# create new val
new='|new_val|'

#put it all back together
echo ${f}${new}${e}
 
1 members found this post helpful.
Old 03-19-2013, 10:34 PM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,256

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
hmmm ... whilst all the posts above would seem ample, I am curious why you do not simply replace the array item as you need?

If we assume your code works as it stands and each item of the pipe separated string is now an individual part of the ADDR array, can't you simply:
Code:
ADDR[26]='new info'
Or have I completely missed something?
 
Old 03-22-2013, 10:42 AM   #8
casperdaghost
Member
 
Registered: Aug 2009
Posts: 349

Original Poster
Rep: Reputation: 16
this is the sting i am working with :
Code:
random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper cap|N||N|C|0|0000994500|S|0000115500
and the script is called : /tmp/foobaz random 999999999 (it is invoked here with a $1 and $2 at the command line)
and yeah - Grail the substitution works !!!!
Code:
#!/bin/bash
stocks=$(egrep "^$1" /data/casper/stocks.txt)
echo "$stocks"


IFS='|' read -ra ADDR <<< "$stocks"

for i in "${ADDR[@]}";
do
    ADDR[26]="$2"
    
    done
echo ${ADDR[@]} | tr " " "|"
however when i put it back together - I have a problems on reassembling the string.

Code:
random|L|N|0|0|1|0|R|0100|T|N|0|0|100|0|1|0|0|0|1|casper|cap|N||N|C|0|9999999999|S|0000115500
the name 'casper cap' should have a space - but it does not.
Keep in mind - i know that i could use awk fields - but want to understand bash arrays.

"If it doesn't challenge you, it doesn't change you!"

Last edited by casperdaghost; 03-22-2013 at 10:44 AM.
 
Old 03-22-2013, 01:11 PM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,256

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Ok ... I get you now. So first off, you do know that your for loop is pointless?? Firstly you never use the 'i' variable and second if you know which element to replace you do not need to loop
over anything.

So the easy answer is, use IFS more:
Code:
#!/bin/bash
stocks=$(egrep "^$1" /data/casper/stocks.txt)
echo "$stocks"

IFS='|'

ADDR=( $stocks )

ADDR[26]="$2"

echo "${ADDR[*]}"

unset IFS
The secret is in the highlighted portion
 
1 members found this post helpful.
Old 03-26-2013, 07:43 PM   #10
casperdaghost
Member
 
Registered: Aug 2009
Posts: 349

Original Poster
Rep: Reputation: 16
this worked great Grail
I wanted so bad to use the arrays in bash, but alas, it was not to be true.
 
Old 03-26-2013, 07:57 PM   #11
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,186

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Quote:
Originally Posted by casperdaghost View Post
this worked great Grail
I wanted so bad to use the arrays in bash, but alas, it was not to be true.
But gail's code does use an array. So it is "true."

The statement ADDR=( $stocks ) loads the array ADDR with the values in ${stocks}, delimited by the pipe symbol.
 
Old 03-28-2013, 05:15 AM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
If you hadn't noticed, the secret is that the '*' array expansion element uses the first character of IFS as its delimiter when printing out the list (be sure to quote it).

So setting IFS to the pipe globally means that it both splits the string into the array and prints the updated array in the same way.

arrays


BTW, grail's code simply used an unquoted variable inside an "arr=()" pattern to set the array. The expanded parameter is word-split according to the current IFS setting, which is then used to set the array. However I would point out that there's a minor risk to this. Since shell globbing is also applied on unquoted parameters, some character in the input could potentially expand into a list of files existing in the PWD, which would also become part of the array.

This can be avoided by also using set +f to turn off glob expansion temporarily. Or you can continue to use read instead, which I personally recommend as the cleaner option.
 
  


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
[SOLVED] bash split array and assign a variable to an element eamesj Programming 3 03-02-2013 01:19 PM
[SOLVED] Compare array index number against element in bash rewtnull Programming 10 11-01-2011 03:53 PM
[SOLVED] BASH SCRIPTING: Help! Yet another check element in array Question kristo5747 Programming 2 07-29-2010 10:47 AM
get index of an element in array in bash mangatmodi Programming 4 11-20-2009 08:45 AM


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

Main Menu
Advertisement
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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration