Multiple strings, Truncate line at 80 characters

StringBashAwk

String Problem Overview


I'm new to awk and sed, and I'm looking for a way to truncate a line at 80 characters, but I'm printing several strings in that line using printf. The last two strings are the ones that give me problems because they vary in size on each iteration of my code. Here's my current code:

printf "%5d  %3s%.2s %4s %s %s \n" "$f" "$month" "$day" "$year" "$from" "$subject"

This code is being used to create a summary of email messages that get passed through a Bash script. What I do know, is that with the spaces and requirements of my other strings, I have room for 60 characters between the $from and $subject strings.

Any help is appreciated.

String Solutions


Solution 1 - String

> I'm looking for a way to truncate a line at 80 characters ...

You could pipe the output to cut:

printf ... | cut -c 1-80

If you wanted to ensure that each line isn't more than 80 characters (or wrap lines to fit in specified width), you could use fold:

printf ... | fold -w 80

Solution 2 - String

Another way to solve this just using Bash (syntax: ${var:0:80}), e.g.:

printf "%5d  %3s%.2s %4s %s %s \n" "$f" "$month" "$day" "$year" "$from" "${subject::80}"

This truncates the string before it gets to printf. This method would also allow you to specify different maximum widths for each printed column individually.

Solution 3 - String

I had the same issue trying to customize my bash prompt with a truncated directory name. What finaly worked was:

PS1='\u@\h:`echo $(basename $PWD) | cut -c 1-15`\$ '

Solution 4 - String

How about a C version?

#include <stdio.h>
int maxline = 80;
int main(int argc, char* argv[])
{
    char line[2048];
    if ((argc>1) && (atoi(argv[1]) > 0)) {
        maxline = atoi(argv[1]);
    }
    while (fgets(line, sizeof(line), stdin)) {
        line[maxline] = '\0';
        printf("%s\n", line);
    }
}

Solution 5 - String

You could use substr to only grab the 1st n characters of from and subject, since you know you only have a max of 60 characters to play with you could grab the 1st 25 of 'from' and the 1st 35 of 'subject'.

#!/usr/bin/gawk -f
BEGIN { 
 # set ouput delimiter to comma
 OFS=","
 #  set input delimiter to bar
 FS="|"  }

{
f=$1
month=$2
day=$3
year=$4
from=$5
subject=$6
from=substr(from,1,25) 
subject=substr(subject,1,35)
printf ("%5d,%3s%.2s,%4s,%s,%s\n",f,month,day,year,from,subject)
}

Running the above on this file

> 12123|Jan|14|1970|[email protected]|"Happy birthday" > 14545|Jan|15|1970|[email protected]|"Hope your head is ok" > 27676|Feb|14|1970|[email protected]|"Still on for tonight?" > 29898|Feb|14|1970|[email protected]|"Sure, if you bring the chocolate." > 34234|Feb|15|1970|[email protected]|"Had a great time last night, > hope you did too. Can't wait for the weekend, love Jack"

Returns

12123,Jan14,1970,jack@overthehill.com,"Happy birthday"
14545,Jan15,1970,jill@thewell.com,"Hope your head is ok"
27676,Feb14,1970,jack@overthehill.com,"Still on for tonight?"
29898,Feb14,1970,jill@thewell.com,"Sure, if you bring the chocolate."
34234,Feb15,1970,jack@overthehill.com,"Had a great time last night, hope

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTZPike05View Question on Stackoverflow
Solution 1 - StringdevnullView Answer on Stackoverflow
Solution 2 - StringAaron R.View Answer on Stackoverflow
Solution 3 - Stringuser5925630View Answer on Stackoverflow
Solution 4 - StringChuckCottrillView Answer on Stackoverflow
Solution 5 - StringPeter KellyView Answer on Stackoverflow