changing a variable length text to a fixed length

Hi,
Can anyone help with a effective solution ?

I need to change a variable length text field (between 1 - 18 characters) to a fixed length text of 18 characters with the unused portion, at the end, filled with spaces.

The text field is actually field 10 of a .csv file however I could cut out the field if it makes it easier.

Thanks
Dave

How about printf?

$ X=abc
$ printf "%-18s" $X
abc               $

so...

$ X=$(printf "%-18s" $X)

You need to change the 10th field in every row to 18 characters?

$ cat file1.csv
1,2,3,4,5,6,7,8,9,10,11,12
a,b,c,d,e,f,g,h,i,j,k,l

$ awk -F, 'BEGIN {OFS=FS} {$10 = sprintf( "%-18s", $10 )}1' file1.csv
1,2,3,4,5,6,7,8,9,10                ,11,12
a,b,c,d,e,f,g,h,i,j                 ,k,l

Hi Scott,
You mention 'change the 10th column' , I need to change the 10th field in the .csv file (the actual start column of field 10 will vary) .... does your solution still apply ?
Dave

Hi.

Actually, I meant to say field.

I would normally say field, but somehow said column :slight_smile: (so, yes!)

I updated my earlier post to remove the confusion.

1 Like

Hi Scott,

I'm afraid your solution only works if there there are no spaces within the text ......... each space found within the text is also padded out to 18 spaces

Dave

Hi.

I don't see this. Can you post an example input that shows this behaviour?

Thanks.

Hi Scott,

Input file

01,10,000020,*,*,******,999999,00,,WERK 28 - BUS
01,10,000030,*,*,******,999999,00,,WERK 30 - UNIMOG
01,10,000060,*,*,******,999999,20,,LASTWAGEN
01,10,000065,*,*,******,999999,00,,WERK 65 - TRANSP.
01,00,000001,*,*,******,999999,00,,DB-PKW
01,00,000010,*,*,******,999999,00,,DB-LKW
01,00,100012,*,*,******,999999,20,,600
01,00,100014,*,*,******,999999,20,,600 LANG 4-T RIG
01,00,100015,*,*,******,999999,20,,600 LANDAUER
01,00,100016,*,*,******,999999,20,,600 LANG 6-T RIG

Output from script, before and after, showing field length & text

   b4 change 13    WERK 28 - BUS
after change 72    WERK              28                -                 BUS
   b4 change 16    WERK 30 - UNIMOG
after change 72    WERK              30                -                 UNIMOG
     b4 change 9    LASTWAGEN
after change 18    LASTWAGEN
   b4 change 17    WERK 65 - TRANSP.
after change 72    WERK              65                -                 TRANSP.
     b4 change 6    DB-PKW
after change 18    DB-PKW
     b4 change 6    DB-LKW
after change 18    DB-LKW
     b4 change 3    600
after change 18    600
   b4 change 16    600 LANG 4-T RIG
after change 72    600               LANG              4-T               RIG
   b4 change 12    600 LANDAUER
after change 36    600               LANDAUER
   b4 change 16    600 LANG 6-T RIG
after change 72    600               LANG              6-T               RIG

Shell Script

cat infile | while read line
do
  field=`echo $line | cut -d',' -f10`
  echo "   b4 change ${#field}    $field"
  field=$(printf "%-18s" $field)
  echo "after change ${#field}    $field"
done

Thanks
Dave

while read line
do
  field=`echo $line | cut -d',' -f10`
  echo "   b4 change ${#field}    $field"
  field=$(printf "%-18s" "$field")
  echo "after change ${#field}    $field"
done < file1

   b4 change 13    WERK 28 - BUS
after change 18    WERK 28 - BUS
   b4 change 16    WERK 30 - UNIMOG
after change 18    WERK 30 - UNIMOG
   b4 change 9    LASTWAGEN
after change 18    LASTWAGEN
   b4 change 17    WERK 65 - TRANSP.
after change 18    WERK 65 - TRANSP.
   b4 change 6    DB-PKW
after change 18    DB-PKW
   b4 change 6    DB-LKW
after change 18    DB-LKW
   b4 change 3    600
after change 18    600
   b4 change 16    600 LANG 4-T RIG
after change 18    600 LANG 4-T RIG
   b4 change 12    600 LANDAUER
after change 18    600 LANDAUER
   b4 change 16    600 LANG 6-T RIG
after change 18    600 LANG 6-T RIG

If you don't quote $field, then the printf will apply the formatting (%-18s) to each part of $field, as separated by whitespace. By quoting it, the printf takes it as one argument.

$ a="1 2 3"
$ a=$(printf "%-18s" $a)
$ echo ${#a}
54

$ a="1 2 3"
$ a=$(printf "%-18s" "$a")
$ echo ${#a}
18
1 Like