Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Heya, any ideas how one can "s 1

Status
Not open for further replies.

vgersh99

Programmer
Jul 27, 2000
2,146
US
Heya,

any ideas how one can "shift" all the fields in a record one position to the "left" starting at a given "field"?

startField=2

input
-----
1 2 3 4 5

output
------
1 3 4 5

I know how to implement it with "loops" and NF - I'm simply looking for a "one-liner" where I can "shift" and print _reevaluated_ record.

vlad
 
Vlad,
"One-liner" :-( I don't think the problem can be solved
without loops. Let, us wait and watch if someone can has
a better solution. P C Das
 
Well.......

I've figured out how to do a "one-liner" for the FIRST field - shifting everything one field to the left starting at field "2". But doing the arbitrary "starting field".... is bit more difficult.

--------------- shiftLeft.awk -----------------------------
BEGIN {
FS=/[ ]+/;
}

{
$0 = substr($0, match($0, "[ ][^ ]")+1); print
}

--------------- shiftLeft.awk -----------------------------

input:
------
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5 6

Any other "bright" ideas?

vlad
 
Experiment with this. Pass in a variable for the field
number and possibly the FS too if required.

nawk '{$2="";sub(" "," ");print}' infile

You need to sub out one space to retain default
field splitting for each arbitrary field you wish to
shift in a record.

HTH


flogrr
flogr@yahoo.com

 
thanks - that does it.

Any idea how to do the same, but shift ALL the way to the left starting at a given position?

vlad
 
Try this vlad-

nawk '{$1=$2=$3="";$0=substr($0,substr($4,1,1),length($0)-1);print}' input

This dumps the first three fields and takes the substr of $0 starting at a designated field.

This in effect makes previous $4 be the new $1 thereby shifting all to the left.

Again, you might want to set it up to use passed in vars for the arbitrary fields and separators.

Good luck with this!


flogrr
flogr@yahoo.com

 

To remove the second field and shift the following ones:

Code:
{ $2=""; $0=$0; $1=$1; print }

This program demonstrates how it works.

Code:
{ pr(1)
  pr()
  $2 = ""
  pr()
  $0 = $0
  pr()
  $1 = $1
  pr()
}

function pr( h,     i )
{ printf "%-15s%2s ", h?"$0":$0, h?"NF":NF
  for (i=1;i<=NF;i++)
    printf "%5s", h?"$"i:$i
  print ""
}

The output is:

[tt]
$0 NF $1 $2 $3 $4 $5 $6
a b c d e f 6 a b c d e f
a c d e f 6 a c d e f
a c d e f 5 a c d e f
a c d e f 5 a c d e f
[/tt]

[tt]$2=""[/tt] changes [tt]$0[/tt] but doesn't change the number of fields.
[tt]$0=$0[/tt] causes the number of fields to be recalculated.
[tt]$1=$1[/tt] causes [tt]$0[/tt] to be rebuilt with [tt]OFS[/tt] between
the fields, thus eliminating the extra space.

flogrr posted:
[tt]
{$1=$2=$3="";$0=substr($0,substr($4,1,1),length($0)-1);print}
[/tt]
This is incorrect. [tt]substr($4,1,1)[/tt] yields the first character
of the 4th field, not a position within [tt]$0[/tt].
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top