Delimit file based on character length using awk


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Delimit file based on character length using awk
# 1  
Old 02-23-2016
Delimit file based on character length using awk

Hi,

I need help with one problem, I came across recently.

I have one input file which I need to delimit based on character length.

Code:
$ cat Input.txt
12345sda231453
asd760kjol62569
sdasw4g76gdf57

And, There is one comma separated file which mentions "start of the field" and "length of the field".

Code:
$ cat start_length.csv
1,2
3,3
6,3
9,

Expected output is as follows:
Code:
12|345|sda|231453
as|d76|0kj|ol62569
sd|asw|4g7|6gdf57

I have used awk to get the expected result as follows:
Code:
$ awk 'BEGIN{OFS="|"}{print substr($0,1,2),substr($0,3,3),substr($0,6,3),substr($0,9)}' Input.txt
12|345|sda|231453
as|d76|0kj|ol62569
sd|asw|4g7|6gdf57

But, the problem here is I have hardcoded "start of the field" and "length of the field" in above awk. We have bigger file containing more than 2 lacs record with more than 200 fields. So, It is not possible to hardcode "start of the field" and "length of the field" for each file.

Is there any way in which I can use start_length.csv file and somehow run it in loop to get desired output.
# 2  
Old 02-23-2016
Hello Prathmesh,

Could you please try following and let me know if this helps you.
Code:
awk 'FNR==NR{A[++i]=$1;B[i]=$2;next} {for(j=1;j<=i;j++){if(B[j]){C=C?C OFS substr($0,A[j],B[j]):substr($0,A[j],B[j])} else {C=C?C OFS substr($0,A[j]):substr($0,A[j])}};print C;C=""}' FS="," fields OFS="|" main_file

Output will be as follows.
Code:
12|345|sda|231453
as|d76|0kj|ol62569
sd|asw|4g7|6gdf57

Thanks,
R. Singh
This User Gave Thanks to RavinderSingh13 For This Post:
# 3  
Old 02-23-2016
Quote:
Originally Posted by RavinderSingh13
Hello Prathmesh,

Could you please try following and let me know if this helps you.
Code:
awk 'FNR==NR{A[++i]=$1;B[i]=$2;next} {for(j=1;j<=i;j++){if(B[j]){C=C?C OFS substr($0,A[j],B[j]):substr($0,A[j],B[j])} else {C=C?C OFS substr($0,A[j]):substr($0,A[j])}};print C;C=""}' FS="," fields OFS="|" main_file

Output will be as follows.
Code:
12|345|sda|231453
as|d76|0kj|ol62569
sd|asw|4g7|6gdf57

Thanks,
R. Singh
Thanks Ravinder. Your code is working fine. But, Can you please explain what it does exactly to understand it better.
# 4  
Old 02-23-2016
Hello Prathmesh,

Could you please go through following and let me know if this helps you.
Code:
  
awk 'FNR==NR{                                         ####### This condition will be TRUE only when first file is being read, because FNR will be RESET for each file but NR(Number of recoreds) value will be keep on increasing till last file read.
A[++i]=$1;                                            ####### Once above condition is TRUE then I am creating an array named A whose index is a variable named i, ++i means increse value of variable i and keep it's value same as $1's(first field's) value.
B[i]=$2;                                              ####### Creating an array named B whose index is variable i(note but not increasing the value of variable i here, to keep the same indexes for array A and B). keeping it's value to $2's value which is second field's value.
next}                                                 ####### putting next statment here to skip further all the next actions now.
{for(j=1;j<=i;j++){                                   ####### Now starting a for loop to run it till the value of variable i, which we will get variable i's final value when first file will be completly read.
if(B[j]){                                             ####### Here I am making sure array B's value is NOT NULL(because in your example at last line last field is empty so during next step doing substr I have to check this condition now.
C=C?C OFS substr($0,A[j],B[j]):substr($0,A[j],B[j])}  ####### Creating a variable named C whose value will appended each time with it's own last time value along with the current line's substring's value(Here I am using array A and array B to get the substring where obvioslu array A is for the starting position and array B denotes then length of string.
else {                                                ####### If above condition is NOT true then this else will be executed.
C=C?C OFS substr($0,A[j]):substr($0,A[j])}};          ####### create a variable named C and each time append itself with variable C with it's current line's substring's value. Here difference between the previous substring and now substring is I am not giving the till value eg--> substr(LINE, STARTING point, END Point); because we may have NO END point like your 3rd line in fields file.
print C;                                              ####### printing the variable named C.
C=""}'                                                ####### Nullyfing the variable C.
FS="," fields                                         ####### Mentioning the field seprator for fields file as comma here. NOTE it will not be for second file, awk gives us this facility to set mutiple field seprators for different files according to our requirements.
OFS="|" main_file                                     #######  Mentioning the output field seprator as | here and mentioning Input_file(main_file) here too.

Thanks,
R. Singh
This User Gave Thanks to RavinderSingh13 For This Post:
# 5  
Old 02-23-2016
For awks that can handle empty field separators, try
Code:
awk 'FNR == NR {S[NR] = $1; CNT = NR; next} {for (i=2; i<=CNT; i++) $S[i] = "|" $S[i]} 1' FS=, file2 FS="" OFS="" file1 
12|345|sda|231453
as|d76|0kj|ol62569
sd|asw|4g7|6gdf57

This User Gave Thanks to RudiC For This Post:
# 6  
Old 02-23-2016
Quote:
Originally Posted by RavinderSingh13
Hello Prathmesh,

Could you please go through following and let me know if this helps you.
Code:
  
awk 'FNR==NR{                                         ####### This condition will be TRUE only when first file is being read, because FNR will be RESET for each file but NR(Number of recoreds) value will be keep on increasing till last file read.
A[++i]=$1;                                            ####### Once above condition is TRUE then I am creating an array named A whose index is a variable named i, ++i means increse value of variable i and keep it's value same as $1's(first field's) value.
B[i]=$2;                                              ####### Creating an array named B whose index is variable i(note but not increasing the value of variable i here, to keep the same indexes for array A and B). keeping it's value to $2's value which is second field's value.
next}                                                 ####### putting next statment here to skip further all the next actions now.
{for(j=1;j<=i;j++){                                   ####### Now starting a for loop to run it till the value of variable i, which we will get variable i's final value when first file will be completly read.
if(B[j]){                                             ####### Here I am making sure array B's value is NOT NULL(because in your example at last line last field is empty so during next step doing substr I have to check this condition now.
C=C?C OFS substr($0,A[j],B[j]):substr($0,A[j],B[j])}  ####### Creating a variable named C whose value will appended each time with it's own last time value along with the current line's substring's value(Here I am using array A and array B to get the substring where obvioslu array A is for the starting position and array B denotes then length of string.
else {                                                ####### If above condition is NOT true then this else will be executed.
C=C?C OFS substr($0,A[j]):substr($0,A[j])}};          ####### create a variable named C and each time append itself with variable C with it's current line's substring's value. Here difference between the previous substring and now substring is I am not giving the till value eg--> substr(LINE, STARTING point, END Point); because we may have NO END point like your 3rd line in fields file.
print C;                                              ####### printing the variable named C.
C=""}'                                                ####### Nullyfing the variable C.
FS="," fields                                         ####### Mentioning the field seprator for fields file as comma here. NOTE it will not be for second file, awk gives us this facility to set mutiple field seprators for different files according to our requirements.
OFS="|" main_file                                     #######  Mentioning the output field seprator as | here and mentioning Input_file(main_file) here too.

Thanks,
R. Singh
Thanks. I will go through it and let you know in case of any doubt.

---------- Post updated at 08:54 PM ---------- Previous update was at 08:50 PM ----------

Quote:
Originally Posted by RudiC
For awks that can handle empty field separators, try
Code:
awk 'FNR == NR {S[NR] = $1; CNT = NR; next} {for (i=2; i<=CNT; i++) $S[i] = "|" $S[i]} 1' FS=, file2 FS="" OFS="" file1 
12|345|sda|231453
as|d76|0kj|ol62569
sd|asw|4g7|6gdf57

Thanks. Can you please explain code.
# 7  
Old 02-23-2016
With FS="", every character is a field of its own. The array S holds the char positions from file2, and file1's fields (= chars) identified by S are prefixed with | .
This User Gave Thanks to RudiC For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Add string based on character length

Good day, I am a newbie here and thanks for accepting me I have a task to modify input data where my input data looks like 123|34567|CHINE 1|23|INDIA 34512|21|USA 104|901|INDIASee that my input has two columns with different character length but max length is 5 and minimum length is 0 which... (1 Reply)
Discussion started by: fastlearner
1 Replies

2. UNIX for Dummies Questions & Answers

Select lines based on character length

Hi, I've got a file like this: 22 22:35645163:T:<CN0>:0 0 35645163 T <CN0> 22 rs140738445:20902439:TTTTTTTG:T 0 20902439 T TTTTTTTG 22 rs149602065:40537763:TTTTTTG:T 0 40537763 T TTTTTTG 22 rs71670155:50538408:TTTTTTG:T 0 50538408 T TTTTTTG... (3 Replies)
Discussion started by: zajtat
3 Replies

3. Shell Programming and Scripting

awk based script to ignore all columns from a file which contains character strings

Hello All, I have a .CSV file where I expect all numeric data in all the columns other than column headers. But sometimes I get the files (result of statistics computation by other persons) like below( sample data) SNO,Data1,Data2,Data3 1,2,3,4 2,3,4,SOME STRING 3,4,Inf,5 4,5,4,4 I... (9 Replies)
Discussion started by: ks_reddy
9 Replies

4. Shell Programming and Scripting

File character adjustment based on specific character

i have a reqirement to adjust the data in a file based on a perticular character the sample data is as below 483PDEAN CORRIGAN 52304037528955WAGES 50000 89BP ABCD MASTER352 5434604223735428 4200 58BP SOUTHERN WA848 ... (1 Reply)
Discussion started by: pema.yozer
1 Replies

5. Shell Programming and Scripting

Awk: Searching for length of words between slash character

Dear UNIX Community, I have a set of file paths like the one below: \\folder name \ folder1 \ folder2 \ folder3 \ folder4 \\folder name \ very long folder name \ even longer name I would like to find the length of the characters (including space) between the \'s. However, I want... (6 Replies)
Discussion started by: vnayak
6 Replies

6. Shell Programming and Scripting

Generate 100 Character Fixed Length Empty File

Hello Everyone, I'm running AIX 5.3 and need to generate a 100 character fixed length empty file from within a bash script that I am developing. I searched and was able to find: dd if=/dev/zero of=/test/path/file count=100 however my understanding is that this will generate a file of a... (10 Replies)
Discussion started by: jvt
10 Replies

7. Shell Programming and Scripting

Add character based on record length

All, I can't seem to find exactly what I'm looking for, and haven't had any luck patching things together. I need to look through a file, and if the record length is not 874, then add 'E' in position 778. Your help is greatly appreciated. (4 Replies)
Discussion started by: CutNPaste
4 Replies

8. Shell Programming and Scripting

print a file with one column having fixed character length

Hi guys, I have tried to find a solution for this problem but couln't. If anyone of you have an Idea do help me. INPUT_FILE with three columns shown to be separated by - sign A5BNK723NVI - 1 - 294 A7QZM0VIT - 251 - 537 A7NU3411V - 245 - 527 I want an output file in which First column... (2 Replies)
Discussion started by: smriti_shridhar
2 Replies

9. Shell Programming and Scripting

Using Awk script to check length of a character

Hi All , I am trying to build a script using awk that checks columns of the înput file and displays message if the column length exceeds 35 char. i have tried the below code but it does not work properly (2 Replies)
Discussion started by: amit1_x
2 Replies

10. UNIX for Dummies Questions & Answers

Need find a file based length

Can some please help me? Want to find files over 35 characters in length? I am running HPUX. Would it be possible with find? Thanks in advance (8 Replies)
Discussion started by: J_ang
8 Replies
Login or Register to Ask a Question