LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
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 01-11-2018, 04:23 AM   #1
SerZKO
LQ Newbie
 
Registered: Jan 2018
Distribution: SuSE
Posts: 6

Rep: Reputation: Disabled
Problems reformating file


I have a problem with file which was reformated during some operation and looks like this:
Code:
18450 0600060009                       25  0 768188519       768188519       0030020124 000 000   10
77019           73587                       25  0 73165           730740506       0160100051 029 000
74049                                       25  0 73950                           1040030047 030 000
14048           14048                       25  0 11833           11833                      022 000
18450 0600060027                       25  0 709948778       709948778       0010030064 000 000   10
                73330                       25  0 0050312875      77020                      000 000
18450 0600040020                       25  0 703820853       703820853       0030020125 000 000   10
And I need it to look like this

Code:
18450 0600060009                       25  0 768188519       768188519       0030020124 000 000   10
77019      73587                       25  0 73165           730740506       0160100051 029 000
74049                                  25  0 73950                           1040030047 030 000
14048      14048                       25  0 11833           11833                      022 000
18450 0600060027                       25  0 709948778       709948778       0010030064 000 000   10
           73330                       25  0 0050312875      77020                      000 000
18450 0600040020                       25  0 703820853       703820853       0030020125 000 000   10
What happened was that column B has shifted 5 places to the right.
I've tried to solve it with a simple oneliner
Code:
while read do printf
but the problem is how to read empty spaces into the variable. Then I've tried perl and substr, but it wouldn't work wll. It looks like sed would be a perfect tool for that, but I just don't know how to do it as any of column where number of digits is greater then 3 can be empty. Any help appreciated
 
Old 01-11-2018, 04:46 AM   #2
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,307
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
Perl or Awk would be a perfect match for this. Can you post the code you have so far so we can see where you are stuck?
 
Old 01-11-2018, 05:14 AM   #3
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
Based on that input, if col 40 != "25" delete (first) 5 spaces. I used sed.

Last edited by syg00; 01-11-2018 at 05:19 AM. Reason: added "(first)"
 
Old 01-11-2018, 06:57 AM   #4
SerZKO
LQ Newbie
 
Registered: Jan 2018
Distribution: SuSE
Posts: 6

Original Poster
Rep: Reputation: Disabled
Code so far

Here is perl try

Code:
#!/usr/bin/perl -w
use strict;

my $infile  =  $ARGV[0];
my $outfile = 'fil.txt';
open my $in,'<',$infile or die "Could not open $infile : $!";
open my $out,'>',$outfile or die "Could not open $outfile : $!";


while (<>){
  chomp;
  my $spaces = substr($_,58,5); 
  if ( $spaces eq '     '){
    substr($_,58,5,'');
    $_ .= $spaces;
  }
  print $out "$_\n";
}
close $in;
close $out;

__END__
It resolves a lot of problems for me, but it seems that I need several itterations to get everything done, because after running a script I've found a row like this:
Code:
17921 087001000                            25  0 60846      60846      1010010014 000 000
                                      25  0 60846      60846      1010010014 000 000     
18450 060006002                            25  0 40976521   40976521   0030020013 000 000
77019     73320                            25  0 73130      702000623  0130060067 030 000
and that's where line begins with a empty spaces...

Last edited by SerZKO; 01-11-2018 at 06:59 AM.
 
Old 01-11-2018, 07:17 AM   #5
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
As you said yourself, column B has apparently been shifted - why are you testing so far away for spaces ?. Especially when it is not always true as you found. See my suggestion above (with limited data admittedly).
 
Old 01-11-2018, 09:33 AM   #6
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Post withdrawn... I misread post #1 and solved the wrong problem!

Daniel B. Martin

Last edited by danielbmartin; 01-11-2018 at 09:36 AM. Reason: Embarrassing goof!
 
Old 01-11-2018, 09:45 AM   #7
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Quote:
Originally Posted by syg00 View Post
Based on that input, if col 40 != "25" delete (first) 5 spaces. I used sed.
Using perl reg exp,
search and capture a number from start of line (digits+ ) or not
followed by 5 spaces
replace with captured (or with nothing)
 
1 members found this post helpful.
Old 01-11-2018, 12:57 PM   #8
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by SerZKO View Post
the problem is how to read empty spaces into the variable.
this will work if you put the IFS to an empty string:
Code:
oldifs="$IFS"
IFS=''
while read line; do
    echo "$line"
done <file
IFS="$oldifs"
assuming bash.
 
Old 01-11-2018, 01:09 PM   #9
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
What I would do is to use a real programming language to read the space-delimited values from the string – a scanf()-type function or a regular-expression could do it easily – then write out the array of values to a new file in the format that you want – e.g. a printf()-type operation.
 
Old 01-11-2018, 02:02 PM   #10
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,790

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Lightbulb temporary environment for a command

Quote:
Originally Posted by ondoho View Post
this will work if you put the IFS to an empty string:
Code:
oldifs="$IFS"
IFS=''
while read line; do
    echo "$line"
done <file
IFS="$oldifs"
assuming bash.
This is how you normally must do it with a for loop.
Here you can set a temporary environment for the read command
Code:
while IFS= read line; do
    echo "$line"
done <file
Advantage: save/restore of IFS is not needed, and further commands in the while-do-done block get the standard IFS.
 
Old 01-11-2018, 02:43 PM   #11
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,790

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
For the original challenge, a sed solution (of course also doable in perl)
Code:
sed '
  :L
  s/^\(.\{6\}\)[[:blank:]]\(.\{32\}[[:blank:]]\)/\1\2/
  tL
' file
It deletes a blank at position 7 until there is no blank at position 40

Last edited by MadeInGermany; 01-11-2018 at 03:20 PM. Reason: indention, delete blank at position 7 not 6
 
1 members found this post helpful.
Old 01-11-2018, 02:52 PM   #12
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
I was thinking of something like
Code:
perl -pe 's/^(\d+)?\s{5}/$1/' file
Or perhaps:
Code:
perl -pe 's/^(?!\s{17})(\d+)?\s{5}/$1/' file
(it you don't want to shift lines that begin with more than 17 space characters)

Last edited by keefaz; 01-11-2018 at 04:07 PM. Reason: Adjusted for special case in post #4
 
1 members found this post helpful.
Old 01-11-2018, 03:38 PM   #13
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,790

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Seeing post#4, where my previous solution stops when the position 7 gets non-blank.
So here is a further attempt to adjust position 40
Code:
sed '
  :L
  s/^\(.\{6\}\)[[:blank:]]\(.\{32\}[[:blank:]]\)/\1\2/
  tL
  s/^\(.\{39\}\)[[:blank:]]*/\1/
' file
 
1 members found this post helpful.
Old 01-11-2018, 04:35 PM   #14
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
Seems like the OP doesn't like our suggestions and opened a duplicate thread. He's my offering.
Code:
sed -r '/^.{39}25/! s/      / /' file
Should use classes, but a quick-and-dirty ....
 
1 members found this post helpful.
Old 01-12-2018, 04:11 AM   #15
SerZKO
LQ Newbie
 
Registered: Jan 2018
Distribution: SuSE
Posts: 6

Original Poster
Rep: Reputation: Disabled
Thanks guys

Hej guys,

Thanks for all help. But it was sed that done it best.

Thanks again !
 
  


Reply



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
Problem reformating a file SerZKO Programming 1 01-11-2018 02:10 PM
Thinking of Reformating Zentharus Ubuntu 10 04-02-2012 03:56 PM
Reformating Harddrive Rollo69 Slackware 1 08-09-2007 08:00 PM
reformating iPod goens Linux - Hardware 2 04-10-2006 01:31 PM
need help reformating hdd! thrustan Linux - Hardware 1 03-10-2005 11:25 AM

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

All times are GMT -5. The time now is 02:50 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