LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-23-2021, 04:28 AM   #1
Midyr
LQ Newbie
 
Registered: Apr 2021
Posts: 3

Rep: Reputation: Disabled
tab seperated textfile and write each field in a variable


Hello,

I have a textfile with tab separate content.

The goal is, to insert fiels3 in some lines.

The first line is without field3.

filed6 contains a space, which makes the trouble
Code:
F1      F2              F4      F5      F 6
F1      F2      F3      F4      F5      F 6
My idea was, to do this with awk, and write each field in a variable but it dosen't work as expected.
Code:
#!/bin/bash

while read 
do 

xy=($(awk -F '\t' '{print $1, $2, $3, $4, $5, $6}' )) 
echo "Status; "${xy[0]}
echo "Start: "${xy[1]}
echo "End: "${xy[2]}
echo "Snr:: "${xy[3]}
echo "Ubknn: "${xy[4]}
echo "CN: "${xy[5]}
done < index.txt
Code:
Status; F1
Start: F2
End: F3
Snr:: F4
Ubknn: F5
CN: F
As you can see, F6 is cuted after the space.

Any idea to this?

Thanks

Midyr
 
Old 04-23-2021, 04:39 AM   #2
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,490

Rep: Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532
you do not need to use awk at all:
https://github.com/koalaman/shellcheck/wiki/SC2206

Code:
xy=($(awk -F '\t' '{print $1, $2, $3, $4, $5, $6}' ))
awk will use tab, but shell will split the line second time using whitespace.
did you check xy[6] ?

Last edited by pan64; 04-23-2021 at 04:42 AM.
 
Old 04-23-2021, 04:50 AM   #3
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 5,611
Blog Entries: 3

Rep: Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859Reputation: 2859
But if you do use AWK, keep in mind that the Field Separator (FS) and the Output Field Separator (OFS) are different variables.

Code:
xy=($(awk 'BEGIN {FS="\t"; OFS="\t"} {print $1, $2, $3, $4, $5, $6}' ))
 
Old 04-23-2021, 04:54 AM   #4
Midyr
LQ Newbie
 
Registered: Apr 2021
Posts: 3

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by pan64 View Post
you do not need to use awk at all:
https://github.com/koalaman/shellcheck/wiki/SC2206

Code:
xy=($(awk -F '\t' '{print $1, $2, $3, $4, $5, $6}' ))
awk will use tab, but shell will split the line second time using whitespace.
did you check xy[6] ?
Yes, xy[6] has the second part, I also tried some escapes, without success
 
Old 04-24-2021, 03:56 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,818

Rep: Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083Reputation: 3083
As the formatting wasn't saved for me on pasting, may I ask what is at field 3 in the line where it is missing?

I have assumed 2 spaces to make up for the missing field, so the below shows how bash can handle this:
Code:
!/usr/bin/env bash

while IFS=$'\t' read -ra fields
do
	printf "##%s##\n" "${fields[@]}"
done<your_file
And the output shows what it would pick up:
Code:
$ ./script.sh 
##F1##
##F2##
##  ##
##F4##
##F5##
##F 6##
##F1##
##F2##
##F3##
##F4##
##F5##
##F 6##

Last edited by grail; 04-24-2021 at 04:03 AM. Reason: Added code
 
Old 04-24-2021, 04:00 AM   #6
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,490

Rep: Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532
Quote:
Originally Posted by Midyr View Post
Yes, xy[6] has the second part, I also tried some escapes, without success
did you check the link I posted? You will see the solution (and explanation too).
 
Old 04-24-2021, 04:13 AM   #7
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 2,321

Rep: Reputation: Disabled
Quote:
Originally Posted by Midyr View Post
The goal is, to insert field3 in some lines.
Then I don't understand what is the purpose of writing out each field to a variable.
Code:
awk -F\\t -vOFS=\\t '1,$3!=""&&$3="NEW"' index.txt
 
Old 05-03-2021, 01:18 AM   #8
Midyr
LQ Newbie
 
Registered: Apr 2021
Posts: 3

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by shruggy View Post
Then I don't understand what is the purpose of writing out each field to a variable.
Code:
awk -F\\t -vOFS=\\t '1,$3!=""&&$3="NEW"' index.txt

Thanks, that's, what i'm locking for!
 
Old 05-04-2021, 08:40 PM   #9
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 1,741

Rep: Reputation: 790Reputation: 790Reputation: 790Reputation: 790Reputation: 790Reputation: 790Reputation: 790
Does it print all lines?
The following has an unconditional and explicit print
Code:
awk 'BEGIN { FS=OFS="\t" } $3=="" { $3="NEW" } { print }' < index.txt
The condition is $3==""

With bash builtins:
have a while read loop over the lines.
There is no good function to print with embedded delimiters,
so here is one.
Code:
#!/bin/bash
fs=$'\t'

prtjoin(){
  local fs=$1
  printf "%s" "$2"
  if [[ $# -gt 2 ]]
  then
    shift 2
    printf "$fs%s\n" "$@"
  fi
  printf "\n"
}

while IFS=$fs read -ra fields
do
  [[ -z ${fields[2]} ]] && fields[2]="NEW"
  prtjoin "$fs" "${fields[@]}"
done < index.txt
The condition is [[ -z ${fields[2]} ]]

And another variant:
Code:
#!/bin/bash
fs=$'\t'
while IFS=$fs read -ra fields
do
  [[ -z ${fields[2]} ]] && fields[2]="NEW"
  out=$(printf "$fs%s" "${fields[@]}"); printf "%s\n" "${out#$fs}"
done < index.txt

Last edited by MadeInGermany; 05-04-2021 at 08:47 PM.
 
Old 05-05-2021, 04:10 AM   #10
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 2,321

Rep: Reputation: Disabled
@MadeInGermany. Two problems with your Bash code:

1) read counts consecutive runs of an IFS character as one delimiter. Probably not was the OP wanted.
2) \n in printf "$fs%s\n" "$@" is unnecessary.

And a small enhancement:
Code:
out=$(printf "$fs%s" "${fields[@]}")
is the same as
Code:
printf -v out "$fs%s" "${fields[@]}"
 
1 members found this post helpful.
Old 05-05-2021, 04:30 AM   #11
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,490

Rep: Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532
or probably
Code:
printf -v out "$fs%s" "${fields[*]}"
 
  


Reply

Tags
csv


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: The first browser to introduce a second level in the tab bar for managing tab groups: Two-Level Tab LXer Syndicated Linux News 0 03-01-2021 05:50 AM
[SOLVED] Bash: copy a whole textfile to write inside another textfile thecazz Programming 6 08-04-2013 02:16 PM
LINUX textfile to WINDOWS textfile bhEsquivel Linux - Software 8 06-03-2011 05:51 PM
[SOLVED] how to find a word in a textfile starting from the BOTTOM of the textfile ? markraem Linux - Software 3 02-08-2010 06:12 AM
have a Variable with multiple lines of data need to have it all on one line seperated xskycamefalling Programming 11 05-12-2009 04:44 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:58 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration