2

I have two files, both contain tens of thousands of lines. I'm currently taking a string (Z1234562) from file_one.txt and trying to see if its on file_two.txt. If it's found on file_two.txt, I'm returning the line number the match was on -- in this case, line 1235. I have this working already.

file_one.txt
Line 1> [...]_Z1234562

file_two.txt
Line 1234> [...],Z1234561,[...]
Line 1235> [...],Z1234562,[...]
Line 1236> [...],Z1234563,[...]

However, I want to now append to line 1235 the string ,Yes. So that on file_two.txt I have

Line 1235> [...],Z1234562,[...],Yes

With the help Glenn Jackman's answer of this other question I was able to figure out how to add text using the ed editor before and after a specific line within a file. However, I haven't been able to figure out if with ed I can add text to the end of a line within a file. Reading the documentation I'm not sure there is. So far, based off this AIX site, this is what I have:

(echo '15022a'; echo 'Text to add.'; echo '.'; echo 'w'; echo 'q') | ed -s filename.txt

This appends the string Text to add. after line 15,022. I'm wondering if there is an insert equivalent to this append.

The reason I'm not using sed is because I'm on an AIX system and I can't seem to get what this forum has working. However, I'm not sure if the sed command in this forum only solves adding text before or after a line and not at the end of the line, which I already have working.

My next approach is to remove the return character at the end of the line I want to append to, append, and then re-add the return character but I don't want to reinvent the wheel before exhausting my options. Maybe I'm missing something as I want to do this as soon as possible but any help would be appreciated. I'm starting not to like these AIX systems. Maybe awk can help me but I'm less familiar with awk.

I wrote a small binary search subroutine using Perl in order to find the line that I want to append to. I'm not sure if sed, ed, grep, awk, etc. use binary search but that's why I'm not using ed or sed's pattern-replace searches. I want it to be as fast as possible so I'm open to a different approach.

Community
  • 1
  • 1
  • How about some verifiable data and an expected output? – James Brown Oct 21 '16 at 21:21
  • if you are using perl for some processing, why not do everything with perl itself? Like @JamesBrown commented, it would help if you lay down entire problem with sample input and expected output.. – Sundeep Oct 22 '16 at 04:21
  • does `file_one.txt` contain only one string? or multiple lines from which you need to extract string after last `_` and for all those strings, you need to append `,Yes` to lines matching in `file_two.txt`? not sure how binary search helps? – Sundeep Oct 22 '16 at 15:49
  • Both files contain tens of thousands of lines. I'm already extracting what I want from **file_one.txt** and are able to find the corresponding string on **file_two.txt**, and are also able to append a string before and after the line that contains the string. However, **I've still to figure out how I can append to the _end_ of the line the string was found on.** – René Alejandro Santiago Oct 22 '16 at 15:57
  • @OP: You should write a program for this. Perl and PHP come to my mind as plausible languages. – Zsigmond Lőrinczy Oct 22 '16 at 17:14
  • Ok you've now explained what you want to do but why are you interested in using `ed` to do it? It'd be absolutely trivial with `awk`. – Ed Morton Oct 22 '16 at 18:43
  • @EdMorton It's all in the text, but here it is: because sed on AIX seems limited, I haven't been able to append anything to a particular line, as opposed to ed with which I was able to. I'm certainly open to suggestions with awk. – René Alejandro Santiago Oct 22 '16 at 19:41
  • @ZsigmondLőrinczy The program that I'm writing _is_ in Perl. – René Alejandro Santiago Oct 22 '16 at 19:43
  • A complete program, I mean, that does the complete process, not only a part of it. The amount of data is few enough, so you can load the files into memory (using a _hash_ for file2). (Note: you might have misread something: shell-scripts are the slowest programs ever, because they keep forking all the time.) – Zsigmond Lőrinczy Oct 23 '16 at 13:10

3 Answers3

3

Here is a general recipe I have used for invoking ed from a script:

(echo '/pattern/s/$/ new text/'
 echo w ) | ed filename

This invokes ed on filename, searches for a line containing pattern, and appends "new text" at the end of that line. Season to taste.

You said you were having trouble with sed, but for the record, here's the same sort of thing using sed:

sed '/pattern/s/$/ new text/' filename > filename.modified
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Sorry, I forgot to say that I wrote a small binary search subroutine using Perl in order to find the line that I want to append to. I'm not sure if sed, ed, grep, awk, etc. use binary search but that's why I'm not using ed or sed's pattern-replace searches. @SteveSummit – René Alejandro Santiago Oct 21 '16 at 23:24
1

You can use the j command

(.,.+1)j Joins the addressed lines. The addressed lines are deleted from the buffer and replaced by a single line containing their joined text. The current address is set to the resultant line.

So you just have to modifiy your previous command :

cat << EOF | ed -s filename.txt
15022a
Text to add.
.
-1,.j
wq
EOF
Adam
  • 17,838
  • 32
  • 54
0

First we create a test file foo:

$ cat > foo
foo
bar

If you already know the line number you want to edit, e.g. previous example and line number 2 using sed:

$ sed '2s/$/foo' foo
foo
barfoo

In awk you'd command:

$ awk 'NR==2 {sub(/$/,"foo")} 1' foo
foo
barfoo

In perl:

$ perl -p -e 's/$/foo/ if $. == 2' foo
foo
barfoo
James Brown
  • 36,089
  • 7
  • 43
  • 59