1

I'm trying to find a string in a file, and when I find that string break it up and perform math on part of it. It sounds like sed won't work because I want to do math and awk will be difficult because I want to update the file in place.

My file looks like this (is an svn diff)

Index: code/foo.c
===================================================================
--- code/foo.c  (revision 13)
+++ code/foo.c  (working copy)
@@ -3,5 +3,5 @@
 int main(int argc, char *argv[])
 {
     printf("I don't like being moved around!\n%s", bar());
-    return 0;
+    return 1;
 }

I'm looking for the @@ line and want to add 1 to the last number before the ending @@. So, @@ -3,5 +3,5 @@ would become @@ -3,5 +3,6 @@

KPK
  • 442
  • 1
  • 5
  • 15
  • 2
    What did you try for yourself? – Inian Dec 03 '18 at 06:06
  • Changing the offsets alone will invalidate the diff. What are you *actually* trying to accomplish? – tripleee Dec 03 '18 at 06:08
  • @tripleee We have an internal tool that merges changes to different branches. But we track changes "differently" across the branches, so I'm inserting a comment to say the automated tool made the change then patching that in. (I already figured out how to insert the comment where needed (which does invalidate the diff), so I'm trying to fix that up) – KPK Dec 03 '18 at 06:34

2 Answers2

4

Could you please try following.

awk '
BEGIN{
  FS=OFS=","
}
/^@@.*@@/{
  split($NF,array," ")
  $NF=array[1]+1" " array[2]
}
1
'   Input_file

In case in you want to save output into Input_file then append > temp_file && mv temp_file Input_file in above code too.

NOTE: In case you are using GNU awk >= 4.1.0 does have an -i inplace in it too.

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • 1
    +1. Just as a point on interest, according to the posix docs, "_All elements of the array shall be deleted before the split is performed._" (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_13_13), so probably the `delete` isn't strictly necessary. – jas Dec 03 '18 at 06:22
  • @jas, sure thanks jas, I have put it in case of $NF is null or not having any values then it shouldn't print previous array's values let me change its place before `split` now. – RavinderSingh13 Dec 03 '18 at 06:27
  • 1
    That's the point; you don't have to worry about that. Try this: `awk 'BEGIN {split("x y z", a); print length(a); split("", a); print length(a)}'` – jas Dec 03 '18 at 06:30
  • @jas, cool got it, I have deleted it now, cheers and thanks for letting know. – RavinderSingh13 Dec 03 '18 at 06:31
  • 1
    Maybe also mention that GNU Awk >= 4.1.0 does have an `-i inplace` option. See also https://stackoverflow.com/questions/16529716/awk-save-modifications-in-place – tripleee Dec 03 '18 at 06:38
  • @tripleee, added GNU `awk` information too now in my post, thanks for letting know. – RavinderSingh13 Dec 03 '18 at 06:52
0

With GNU awk for the 3rd arg to match():

$ awk 'match($0,/^(@@.*,)([0-9]+)( @@)$/,a){$0=a[1] a[2]+1 a[3]} 1' file
Index: code/foo.c
===================================================================
--- code/foo.c  (revision 13)
+++ code/foo.c  (working copy)
@@ -3,5 +3,6 @@
 int main(int argc, char *argv[])
 {
     printf("I don't like being moved around!\n%s", bar());
-    return 0;
+    return 1;
 }
Ed Morton
  • 188,023
  • 17
  • 78
  • 185