1

I am trying to compare two text files but I need to edit them first to ignore certain strings. Here is an example of one text file:

Processing Server ABC-123
oracle   10785     1  0 May17 ?        00:00:21 asm_smon_+ASM
oracle   11151     1  0 May17 ?        00:00:15 ora_smon_CSEREF
oracle   11656     1  0 May17 ?        00:00:16 ora_smon_prblogp
Processing Server ABC-456
Processing Server ABC-789
oracle      5514       1  0 May20 ?        00:00:13 asm_smon_+ASM
oracle      5777       1  0 May20 ?        00:00:11 ora_smon_COGCV05

The goal is to have it look like this:

Processing Server ABC-123
asm_smon_+ASM
ora_smon_CSEREF
ora_smon_prblogp
Processing Server ABC-456
Processing Server ABC-789
asm_smon_+ASM
ora_smon_COGCV05

I believe I'm trying to achieve two things:

  1. ignore/leave all lines that begin with Processing and
  2. identify all the lines that contain ora or asm and delete all the strings before them.

I have played around with awk and sed but I cannot seem to find the right combination of codes for my particular scenario.

3
  • Hi there! If you show what you tried, we can point out what went wrong, so you can learn from it. Otherwise someone will likely post just some code, that will work for the example, but fail in real life because you don't understand it.
    – Philippos
    Commented Jun 15, 2023 at 15:55
  • seems you want awk 'NF>3{ print $NF }1' yourfile for the given example data file. be aware that it won't filter based on anything else. Commented Jun 15, 2023 at 16:04
  • I have tried: awk '{print $8}' thetextfile.txt but that doesn't leave/print the server names, which I need. I tried sed -i '/oracle/d' thetextfile.txt but that gave me the opposite problem and only left me the server names. I need to combine them somehow
    – user575954
    Commented Jun 15, 2023 at 16:06

4 Answers 4

2

For this kind of thing, I usually define a function that transforms the input like here:

transform() { awk '{print /^Processing/ ? $0 : $NF}' "$@"; }

Or:

transform() {
  awk '/^Processing/ {print; next}
       $NF ~ /^(ora|asm)/ {print $NF; next}' "$@"
}

Or:

transform() { grep -Po '^Processing.*|(?<!\S)(ora|asm)\S*$' "$@"; }

Assuming GNU grep or compatible built with perl-like regexp support.

And then assuming a shell with process substitution or process redirection support:

  • ksh / zsh / bash
    diff -u <(transform<file1) <(transform<file2)
    
  • yash
    diff -u /dev/fd/3 3<(transform<file1) /dev/fd/4 4<(transform<file2)
    
  • rc or derivatives (though the function definition syntax is also different there)
    diff -u <{transform<file1} <{transform<file2}
    
  • fish (though the function definition syntax is also different there)
    diff -u (transform<file1|psub) (transform<file2|psub)
    
1

Using any awk:

$ awk '{print $(NF>3 ? NF : 0)}' file
Processing Server ABC-123
asm_smon_+ASM
ora_smon_CSEREF
ora_smon_prblogp
Processing Server ABC-456
Processing Server ABC-789
asm_smon_+ASM
ora_smon_COGCV05

You don't NEED to edit the files before comparing though if you just compare the parts you're interested in, e.g. with these 2 input files that differ in the key values at lines 3 and 5 and differ in non-key values at lines 2 and 8:

$ head file{1,2}
==> file1 <==
Processing Server ABC-123
oracle   10785     1  0 May17 ?        00:00:21 asm_smon_+ASM
oracle   11151     1  0 May17 ?        00:00:15 ora_smon_CSEREF
oracle   11656     1  0 May17 ?        00:00:16 ora_smon_prblogp
Processing Server ABC-456
Processing Server ABC-789
oracle      5514       1  0 May20 ?        00:00:13 asm_smon_+ASM
oracle      5777       1  0 May20 ?        00:00:11 ora_smon_COGCV05

==> file2 <==
Processing Server ABC-123
oracle   99999     1  0 May17 ?        00:00:21 asm_smon_+ASM
oracle   11151     1  0 May17 ?        00:00:15 here_we_go
oracle   11656     1  0 May17 ?        00:00:16 ora_smon_prblogp
Processing Server FOO-999
Processing Server ABC-789
oracle      5514       8  0 May20 ?        00:00:13 asm_smon_+ASM
oracle      5777       1  0 May20 ?        00:00:11 ora_smon_COGCV05

we can find all the differences with diff:

$ diff file{1,2}
2,3c2,3
< oracle   10785     1  0 May17 ?        00:00:21 asm_smon_+ASM
< oracle   11151     1  0 May17 ?        00:00:15 ora_smon_CSEREF
---
> oracle   99999     1  0 May17 ?        00:00:21 asm_smon_+ASM
> oracle   11151     1  0 May17 ?        00:00:15 here_we_go
5c5
< Processing Server ABC-456
---
> Processing Server FOO-999
7c7
< oracle      5514       1  0 May20 ?        00:00:13 asm_smon_+ASM
---
> oracle      5514       8  0 May20 ?        00:00:13 asm_smon_+ASM

but we can find just the key value changes with:

$ awk '
    { key=$(NF>3 ? NF : 0) }
    NR==FNR { a[NR]=key} a[FNR] != key{print FNR , "<", a[FNR] ORS FNR, ">", key }
' file{1,2}
3 < ora_smon_CSEREF
3 > here_we_go
5 < Processing Server ABC-456
5 > Processing Server FOO-999

Tweak the output format as you like.

0

How about this:

serverTracking.log (notice bogus entries for testing purposes)

Processing Server ABC-123
oracle   10785     1  0 May17 ?        00:00:21 asm_smon_+ASM
oracle   11151     1  0 May17 ?        00:00:15 ora_smon_CSEREF
oracle   22231     2  0 May17 ?        00:00:16 som_other_TYPE
oracle   11656     1  0 May17 ?        00:00:16 ora_smon_prblogp
Processing Server ABC-456
Processing Server ABC-789
oracle      5514       1  0 May20 ?        00:00:13 asm_smon_+ASM
oracle      5777       1  0 May20 ?        00:00:11 ora_smon_COGCV05
oracle      5674       1  0 May20 ?        00:00:14 som_other_type

SED SCRIPT (using Ubuntu bash)

sed -E -n 's/(.* asm_.*)|(.* ora_.*)|(Processing Server.*)/\1\2\3/p' serverTracking.log | sed -E 's/(.*[0-9]*.:[0-9]*.:[0-9]*[[:blank:]]*)//' > serverTrackingFiltered.log

serverTrackingFiltered.log

Processing Server ABC-123
asm_smon_+ASM
ora_smon_CSEREF
ora_smon_prblogp
Processing Server ABC-456
Processing Server ABC-789
asm_smon_+ASM
ora_smon_COGCV05
2
  • 2
    ITYM sed -E -n 's/.* (asm_.*)|.* (ora_.*)|(Processing Server.*)/\1\2\3/p' or sed -E -n 's/.* ((asm|ora)_.*)|(Processing Server.*)/\1\3/p' Commented Jun 16, 2023 at 6:59
  • Or simply sed -E '/^Processing Server/!s/.* (asm_.*|ora_.*)/\1/'?
    – Philippos
    Commented Jun 16, 2023 at 13:47
0

Thanks for all your help, guys! All of your suggestions worked in different ways but the commands that worked for me were:

sed -E -n 's/(.* asm_.*)|(.* ora_.*)|(Processing Server.*)/\1\2\3/p' BEFORE_FILE.txt | sed -E 's/(.*[0-9]*.:[0-9]*.:[0-9]*[[:blank:]]*)//' > /FOLDER/BEFORE_OUTPUT.log
sed -E -n 's/(.* asm_.*)|(.* ora_.*)|(Processing Server.*)/\1\2\3/p' AFTER_FILE.txt | sed -E 's/(.*[0-9]*.:[0-9]*.:[0-9]*[[:blank:]]*)//' > /xFOLDER/AFTER_OUTPUT.log

Then I used MobaDiff to compare both files. Worked like a charm!

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .