[SOLVED] Replacing word occurance with an increasing number in a file using bash
Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Well I would not agree with the method you are using, but the reason your for statement is not working is you assign it 2 different values.
Firstly the value 1 and then the value 100. Let us have a look at the for statement make up and see if that helps you:
for(<blah>;<foo>;<bar>)
for - command or statement to be used
<blah> - set variable to initial value
<foo> - provide a reason (expression) to stop
<bar> - increase variable by a set amount
Your issue is at the <foo> stage as you have assigned to equal 100 instead of testing when does it equal 100
I'm not sure why you would want to do that within the file when you can enumerate the lines as the file is read. For example, when using cat -n or a text editor like vi. Is this a homework question from college?
No, not homework. I attempted to make it as general as possible, so I can understand the reasoning.
What I'm writing it for is an output file from a different program. In short, the program runs something, names the cycle=x on one line, provides stuff I need, then a variable amount of data. Earlier, each run was labeled cycle=1, cycle=2 etc, so that was simply a case of using "grep -A $numberoflines cycle=$a", successfully using the "for ((a=1; a<=100 ; a++))" to strip that from a file, and do what I wanted to it:
However, under a different option the cycle runs for each point a few times and spits the final answer out, causing cycle=13,cycle=25,cycle=5 etc. making the previous method useless
From what I understood, the "for ((a=1; a<=100 ; a++))" line says start at 1, then go to another number (in this case 100) at regular intervals (a++), however it seems I'm wrong with this interpretation.
The awk method does work and is murderously simple, but is admittedly something I haven't looked at at all yet (but this is a newbie forum, right? )
From what I understand from other posters I'm missing something small and easy to find from my first attempt, which I also admittedly haven't figured out yet, but I'll keep you posted.
sed isn't really the right tool for this: starting 10000 processes for a 10000 line file is ... not aesthetically pleasing. Plus, in circumstances other than casual use it can actually turn into a performance problem. So get used to avoiding things like that.
The awk oneliner is probably best:
Code:
awk '/start/{sub(/start/,++n);{print}'
or if you want the substitution only on lines that contain *only* 'start',
Code:
awk '/^start$/{$0=++n};{print}'
but you can do it without ever leaving bash if you want. The whole-line case is really easy. I'll explain the IFS stuff in a minute.
Code:
IFS='' n=0; while read; do [[ $REPLY == start ]] && REPLY=$((++n))
echo $REPLY; done
unset IFS
and bash's parameter expansion can do quite a lot -- it's (relative to what bash can do) also easy to do the more general substitution in bash:
The shell uses the 'IFS' variable to decide where to split in its input. The 'read' command distributes the parameters into the variables you give it, or 'REPLY' if you don't give it one. With the default IFS, that means whitespace sequences are collapsed to a single space. Setting IFS to '' tells the shell to not do any parameter splitting. Do remember to unset it afterwards. Or you could leave it unset if you want the default behavior.
I think OP made a slight mistake in his sample file: 'start' is a literal, but 'content content' is not. Therefore you cannot expect a search for "content" to be useful. As I said, I would use awk & jthill was kind enough to provide 2 awk-based solutions.
twoleggedtripod,
It's a custom at LQ to give positive feedback to to those who tried to help you by telling what solution you adopted. That also helps create an archive of solutions for others in the future. Please give back to LQ, don't be a taker only.
Last edited by archtoad6; 08-08-2010 at 12:31 PM.
Reason: typo
sed is powerfull ---- not as powerfull as "awk" but way easier
[root@hostest ~]# cat text.txt
start
contantly changing content content
start
mary had a little lamb
start
and everwhere mary went
[root@hostest ~]#
[root@hostest ~]#
[root@hostest ~]# sed '/^start/d' it.txt |cat -n |sed 's/\t.*/\n&/'
1
contantly changing content content
2
mary had a little lamb
3
and everwhere mary went
[root@hostest ~]#
In short, the program runs something, names the cycle=x on one line, provides stuff I need, then a variable amount of data.
I take "variable amount of data" to mean possibly more than one line. The sed approaches posted so far don't allow for that. I still think awk is the right tool for this job.
BTW, using '/' for the delimiter in a regex in both sed & perl is optional -- any character is allowed (RTM).
Also, FWIW, code samples & ASCII files are best put in "Code:" blocks when posting on LQ. Long or wide ones go better in a pastebin.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.