Find similar numbers from a txt file and save the matched numbered lines in different txt

Viewed 140

The main txt (data.txt) contains for example:

Lib ID 4444
QT ID 4444
SOQ ID 80
MAC ID 21563
LED ID 4444
TRD ID 80
CAD ID 31256
OIL ID 21563
MNO ID 3315
TOP ID 638

And the list goes on. The numbers are from minimum 2 to 5 digits. What I am trying to do is to match the same numbers and save them in separated txt files. The files can be saved by the number's name or it can be anything random. For example, it will save the below IDs in a separate txt file (4444.txt or random.txt):

LED ID 4444
QT ID 4444
Lib ID 4444

It will save 80 in different txt:

TRD ID 80
SOQ ID 80

Save another match in different txt:

OIL ID 21563
MAC ID 21563

And the lines with unique numbers will be saved in a different txt for example (unique.txt):

MNO ID 3315
TOP ID 638
CAD ID 31256

I have tried using this regex: (\d)(?!\1+$)\d*

it matches the similar numbers but I am stuck on separating them. Any help will be greatly appreciated.

4 Answers
$ cat tst.awk
{
    if ( $3 in key2out ) {
        out = key2out[$3]
        if ( $3 in key2first ) {
            print key2first[$3] > out
            delete key2first[$3]
        }
        print >> out
        close(out)
    }
    else {
        key2out[$3] = $3 ".txt"
        key2first[$3] = $0
    }
}
END {
    for (key in key2first) {
        print key2first[key] > "unique.txt"
    }
}

$ awk -f tst.awk file
$ head *.txt
==> 21563.txt <==
MAC ID 21563
OIL ID 21563

==> 4444.txt <==
Lib ID 4444
QT ID 4444
LED ID 4444

==> 80.txt <==
SOQ ID 80
TRD ID 80

==> unique.txt <==
TOP ID 638
MNO ID 3315
CAD ID 31256

Another awk that creates files named 1 ... n (var f in code):

$ awk '{
    if(!($3 in a) && !($3 in u)) {
        u[$3]=$0
        next
    }
    if($3 in u) {                    # u hash holds uniques
        a[$3]=++f                    # file naming happens here
        print u[$3] >> a[$3]    
        print >> a[$3]
        close(a[$3])
        delete u[$3]                 # delete from unique hash when not unique anymore
        next
    }
    print >> a[$3]
    close(a[$3])
}
END {                                # in the end 
    f++
    for(i in u)                      # print all uniques to last file
        print u[i] > f
}' file
@ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q66304300.txt"

FOR /f "usebackqtokens=1,2,*delims= " %%u IN ("%filename1%") DO (ECHO %%u %%v %%w)>>"%destdir%\%%w.txt"
FOR /f %%e IN ('dir /b /a-d "%destdir%\*.txt"') DO (
 SET "multiline="
 FOR /f "usebackqskip=1" %%b IN ("%destdir%\%%e") DO SET "multiline=%%b"
 IF NOT DEFINED multiline TYPE "%destdir%\%%e">>"%destdir%\oncers.txt"&DEL "%destdir%\%%e"
)

GOTO :EOF

from each line in the sourcefile, select each of the 3 columns to %%u, %%v, %%w and append to a filename (3rd column).txt in a presumed-empty destination directory.

Then read each file from the destination directory. If it has only 1 line, then append it to oncers.txt in the destination directory and delete it.

With your shown samples, could you please try following. Written and tested with GNU awk.

awk '
FNR==NR{
  arr[$NF]++
  next
}
arr[$NF]==1{
  print > ("unique.txt")
  next
}
arr[$NF]>1{
  outFile=$NF".txt"
  print >> (outFile)
  close(outFile)
}
'  Input_file Input_file

Explanation: Adding detailed explanation for above.

awk '                       ##Starting awk program from here.
FNR==NR{                    ##Checking condition which will be TRUE when Input_file is being read first time.
  arr[$NF]++                ##Creating arr with index of last field and increasing it 1 each time it comes with same one.
  next                      ##next will skip all further statements from here.
}
arr[$NF]==1{                ##Checking condition if any value(last field) occurs only 1 time in whole Input_file then do following.
  print > ("unique.txt")    ##Printing current line to unique.txt output file.
  next                      ##next will skip all further statements from here.
}
arr[$NF]>1{                 ##Checking condition if last field comes more than 1 then do following.
  outFile=$NF".txt"         ##Creating outFile variable with last field .txt to it.
  print >> (outFile)        ##Printing current line to output file here.
  close(outFile)            ##Closing output file in backend to avoid "too many opened files" error.
}
'  Input_file Input_file    ##Mentioning Input_file(s) here.
Related