how to insert a new line with text before the match - parsing

I was able to extract these lines from a text file
TBL Papers
Papers_ShortName "TPJ341861"
Papers_Name "BANK 240314 341861 "
MMInstrumentType P "Discounted Paper"
but wanted to insert a new line( text before the match TBL Papers). see expected output
ACTION "INS"
TBL Papers
Papers_ShortName "TPJ341861"
Papers_Name "BANK 240314 341861 "
MMInstrumentType P "Discounted Paper"
How do I do that ? thanks

Using awk
awk '/TBL Papers/ {$0="ACTION \"INS\"" RS$0}8' file
ACTION "INS"
TBL Papers
Papers_ShortName "TPJ341861"
Papers_Name "BANK 240314 341861 "
MMInstrumentType P "Discounted Paper"
This code will add a line above pattern TBL Papers and then print everything out.

awk '/TBL Papers/{ print "ACTION \"INS\"" } 1' file

Related

Join multiple lines into One (.cap file) CentOS

Single entry has multiple lines. Each entry is separated by two blank lines.
Each entry has to be made into a single line followed by a delimiter(;).
Sample Input:
Name:Sid
ID:123
Name:Jai
ID:234
Name:Arun
ID:12
Tried replacing the blank lines with cat test.cap | tr -s [:space:] ';'
Output:
Name:Sid;ID:123;Name:Jai;ID:234;Name:Arun;ID:12;
Expected Output:
Name:SidID:123;Name:JaiID:234;Name:ArunID:12;
Same is the case with Xargs.
I've used sed command as well but it only joined two lines into one. Where as I've 132 lines as one entry and 1000 such entries in one file.
You may use
cat file | awk 'BEGIN { FS = "\n"; RS = "\n\n"; ORS=";" } { gsub(/\n/, "", $0); print }' | sed 's/;;*$//' > output.file
Output:
Name:SidID:123;Name:JaiID:234;Name:ArunID:12
Notes:
FS = "\n" will set field separators to a newline`
RS = "\n\n" will set your record separators to double newline
gsub(/\n/, "", $0) will remove all newlines from a found record
sed 's/;;*$//' will remove the trailing ; added by awk
See the online demo
Could you please try following.
awk 'NF{val=(val?$0~/^ID/?val $0";":val $0:$0)} END{print val}' Input_file
Output will be as follows.
Name:SidID:123;Name:JaiID:234;Name:ArunID:12;
Explanation: Adding explanation of above code too now.
awk ' ##Starting awk program here.
NF{ ##Checking condition if a LINE is NOT NULL and having some value in it.
val=(val?$0~/^ID/?val $0";":val $0:$0) ##Creating a variable val here whose value is concatenating its own value along with check if a line starts with string ID then add a semi colon at last else no need to add it then.
}
END{ ##Starting END section of awk here.
print val ##Printing value of variable val here.
}
' Input_file ##Mentioning Input_file name here.
This might work for you (GNU sed):
sed -r '/./{N;s/\n//;H};$!d;x;s/.//;s/\n|$/;/g' file
If it is not a blank line, append the following line and remove the newline between them. Append the result to the hold space and if it is not the end of the file, delete the current line. At the end of the file, swap to the hold space, remove the first character (which will be a newline) and then replace all newlines (append an extra semi-colon for the last line only) with semi-colons.

AWK - Merge multiple lines in two particular columns into one line?

Newbie here.. I'm confused how to merge multiple lines in particular columns and print into one row. For example I have this kind of data in .csv file (separated by comma):
ID1,X1,X2,X3,X4,X5,X6,T,C
ID2,X1,X2,X3,X4,X5,X6,G,A
ID3,X1,X2,X3,X4,X5,X6,C,G
ID4,X1,X2,X3,X4,X5,X6,A,A
I plan to select only the 8th and 9th columns per-row, and print them all in one row and separated using whitespace, so that the result will be like this:
T C G A C G A A
To do that, I tried to use AWK code :
awk -F "," '{printf "%s ",$8, "%s ",$9}' FILE > outputfile
But it gave result the merge between all in col 8th then all in col 9th:
T G C A C A G A
Any suggestions are very welcomed.
Thank you very much for your kind help.
like this?
kent$ awk -F, '{t=$8 OFS $9;s=s?s OFS t:t}END{print s}' file
T C G A C G A A
Try this awk:
awk -F "," '{printf "%s %s ", $8,$9}' yourfile

Powershell parse parts of a text file and save to CSV

All, I'm very new to powershell and am hoping someone can get me going on what I think would be a simple script.
I need to parse a text file, capture certain lines from it, and save those lines as a csv file.
For example, each alert is in its own text file. Each file is similar to this:
--start of file ---
Name John Smith
Dept Accounting
Codes bas-2349,cav-3928,deg-3942
iye-2830,tel-3890
Urls hxxp://blah.com
hxxp://foo.com, hxxp://foo2.com
Some text I dont care about
More text i dont care about
Comments
---------
"here is a multi line
comment I need
to capture"
Some text I dont care about
More text i dont care about
Date 3/12/2013
---END of file---
For each text file if I wanted to write only Name, Codes, and Urls to a CSV file. Could someone help me get going on this?
I'm more a PERL guy so I know I could write a regex for capturing a single line beginning with Name. However I am completely lost on how I could read the "Codes" line when it might be one line or it might be X lines long until I run into the Urls field.
Any help would be greatly appreciated!
Text parsing usually means regex. With regex, sometimes you need anchors to know when to stop a match and that can make you care about text you otherwise wouldn't. If you can specify that first line of "Some text I don't care about" you can use that to "anchor" your match of the URLs so you know when to stop matching.
$regex = #'
(?ms)Name (.+)?
Dept .+?
Codes (.+)?
Urls (.+)?
Some text I dont care about.+
Comments
---------
(.+)?
Some text I dont care about
'#
$file = 'c:\somedir\somefile.txt'
[IO.File]::ReadAllText($file) -match $regex
if ([IO.File]::ReadAllText($file) -match $regex)
{
$Name = $matches[1]
$Codes = $matches[2] -replace '\s+',','
$Urls = $matches[3] -replace '\s+',','
$comment = $matches[4] -replace '\s+',' '
}
$Name
$Codes
$Urls
$comment
If the file is not too big to be processed in memory, the simple way is to read it as an array of strings. (What too big means is subject to your system. Anything sub-gigabyte should work without too much a hickup.)
After you've read the file, set up a head and tail counters to point to element zero. Move the tail pointer row by row forward, until you find the date row. You can match data with regexps. Now you know the start and end of a single record. For the next record, set head counter to tail+1, tail to tail+2 and start scanning rows again. Lather, rinse, repeat until end of array is reached.
When a record is matched, you can extract name with a regex. Codes and Urls are a bit trickier. Match the Codes row with a regex. Extract it and all the next rows unless they do not match the code pattern. Same goes to Urls data. If the file always has whitespace padding on rows that are data to previous Urls and Codes, you could use match whitespace count with a regexp to get data rows too.
Maybe something line this would to it:
foreach ($Line in gc file.txt) {
switch -regex ($Line) {
'^(Name|Dept|Codes|Urls)' {
$Capture = $true
break
}
'^[A-Za-z0-9_-]+' {
$Capture = $false
break
}
}
if ($Capture) {
$Line
}
}
If you want the end result as a CSV file then you may use the Export-Csv cmdlet.
According the fact that c:\temp\file.txt contains :
Name John Smith
Dept Accounting
Codes bas-2349,cav-3928,deg-3942
iye-2830,tel-3890
Urls hxxp://blah.com
hxxp://foo.com
hxxp://foo2.com
Some text I dont care about
More text i dont care about
.
.
Date 3/12/2013
You can use regular expressions like this :
$a = Get-Content C:\temp\file.txt
$b = [regex]::match($a, "^.*Codes (.*)Urls (.*)Some.*$", "Multiline")
$codes = $b.groups[1].value -replace '[ ]{2,}',','
$urls = $b.groups[2].value -replace '[ ]{2,}',','
If all files have the same structure you could do something like this:
$srcdir = "C:\Test"
$outfile = "$srcdir\out.csv"
$re = '^Name (.*(?:\r\n .*)*)\r\n' +
'Dept .*(?:\r\n .*)*\r\n' +
'Codes (.*(?:\r\n .*)*)\r\n' +
'Urls (.*(?:\r\n .*)*)' +
'[\s\S]*$'
Get-ChildItem $srcdir -Filter *.txt | % {
[io.file]::ReadAllText($_.FullName)
} | Select-String $re | % {
$f = $_.Matches | % { $_.Groups } | ? { $_.Index -gt 0 }
New-Object -TypeName PSObject -Prop #{
'Name' = $f[0].Value;
'Codes' = $f[1].Value;
'Urls' = $f[2].Value;
}
} | Export-Csv $outfile -NoTypeInformation

FOREACH I4GL SE

I am trying to get the customers last name, first name - dob, I am getting all but everything printing the same place, any idea?
declare n_curs cursor for
select unique pin,surname,given1,given2,dob from crcharge where
chargenum in (select chargenum from crbookdd where book_no = rpt.book_no)
order by surname,given1
print ESC, "&l4E"
foreach n_curs into t_pin, t_surname, t_given1, t_given2, t_dob
if kick_new then
print column 1, ESC, "&a0G", ESC, "&l3O", ESC, "&f4y3X",
ESC, "&l8D",ESC, "&l4E"
end if
let shtwrd_count = 0
if shtwrd_count > 6 then
let shtwrd[shtwrd_count] = t_shtwrd
let shtwrd_count = shtwrd_count + 1
Exit foreach
end if
print
print ESC,"&a6R", ESC, "&a3C",
upshift(t_surname) clipped, ",",
updown(t_given1) clipped," " ,
updown(t_given2) clipped,"-", t_dob clipped;
end foreach
Because your escape sequence is suppressing the LF (Line Feed) after the CR (Carriage return).
The semi-colon after the PRINT statement means 'suppress newline'. The next PRINT statement continues on the same line, therefore. Very useful when that's the effect you want; otherwise, not good.
Separately, as some advice, you should parameterize the escape sequences. If you don't, then life will become really difficult when you need to change printer or terminal type. Create functions which name the effect and return the correct string:
FUNCTION extra_bold()
RETURN ESC, "&a6R" -- Or whatever
END FUNCTION
Then use them:
PRINT extra_bold(), info.field

Excel parse cell value

I have placed the following in cell A1:
"a lot of text marker: xxx some more text"
I would like to copy the xxx value into cell A2.
Any suggestions on how this could be done?
Thanks
=MID(A1, FIND("marker:",A1) + LEN("marker:"), 4)
I am assuming that the xxx (per your example) is 3 characters long and a space is present between "marker:" and "xxx".
Just my two cents. Find() is case sensitive so if the text in A1 is
"a lot of text Marker: xxx some more text"
Then Find will give you an error.
You can use Search() in lieu of FIND()
=MID(A1, SEARCH("marker: ",A1) + LEN("marker: "), 3)
Also depending upon your regional settings you might have to use ";" instead of ","
If you wanted a VBA solution, this worked for me using your sample input:
Function GetValue(rng As Excel.Range) As String
Dim tempValue As String
Dim arrValues() As String
' get value from source range
tempValue = rng.value
' split by ":" character
arrValues = Split(tempValue, ":")
' split by spaces and take the second array element
' because there is a space between ":" and "xxx"
GetXXXValue = Trim$(Split(arrValues(1), " ")(1))
End Function
To use, put this code into the sheet module (see Where do I paste the code that I want to use in my workbook for placement assistance) and then put the following into cell A2:
=GetValue(A1)

Resources