3 save another 2 chars because parens aren't needed at all in the fn def
source | link

Bash, 6062, 61+feature, 59

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width onas stdina function arg: 6359 chars
read N;whilef()while read -n$Nrn$1 r;do [[ $r ]]&&printf %$N's\n'%$1s\\n "$r";done
# width as a functionon argstdin: 6264 chars
f  (not updated with later suggestions&ideas)(while
read N;while read -n$1rn$N r;do [[ $r ]]&&printf %$1s\\n%$N's\n' "$r";done)

This fails to handle two special cases of input data: empty lines, and \ in the input. Otherwise, this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -rn$Nn$N saves one character, but lets (one extra character) would avoid mungingread munge \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f(){ (while read -n$1rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}"$r";done); (echo 4; echo -e "*";"*\n\\"; cat /tmp/lines) | f 4

Bash, 60

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width on stdin: 63 chars
read N;while read -n$N r;do [[ $r ]]&&printf %$N's\n' "$r";done
# width as a function arg: 62 chars
f()(while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done)

This fails to handle two special cases of input data: empty lines, and \. Otherwise this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -rn$N, (one extra character) would avoid munging \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}; (echo 4; echo -e "*"; cat /tmp/lines) | f 4

Bash, 62, 61+feature, 59

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width as a function arg: 59 chars
f()while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done
# width on stdin: 64 chars  (not updated with later suggestions&ideas)
read N;while read -rn$N r;do [[ $r ]]&&printf %$N's\n' "$r";done

This fails to handle empty lines in the input. Otherwise, this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -n$N saves one character, but lets read munge \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f()(while read -rn$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done); (echo 4; echo -e "*\n\\"; cat /tmp/lines) | f 4
2 define functions with fn()(code)
source | link

Bash, 6260

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width on stdin: 63 chars
read N;while read -n$N r;do [[ $r ]]&&printf %$N's\n' "$r";done
# width as a function arg: 62 chars
f(){ (while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}"$r";done)

This fails to handle two special cases of input data: empty lines, and \. Otherwise this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -rn$N, (one extra character) would avoid munging \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}; (echo 4; echo -e "*"; cat /tmp/lines) | f 4

Bash, 62

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width on stdin: 63 chars
read N;while read -n$N r;do [[ $r ]]&&printf %$N's\n' "$r";done
# width as a function arg: 62 chars
f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}

This fails to handle two special cases of input data: empty lines, and \. Otherwise this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -rn$N, (one extra character) would avoid munging \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}; (echo 4; echo -e "*"; cat /tmp/lines) | f 4

Bash, 60

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width on stdin: 63 chars
read N;while read -n$N r;do [[ $r ]]&&printf %$N's\n' "$r";done
# width as a function arg: 62 chars
f()(while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done)

This fails to handle two special cases of input data: empty lines, and \. Otherwise this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -rn$N, (one extra character) would avoid munging \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}; (echo 4; echo -e "*"; cat /tmp/lines) | f 4
1
source | link

Bash, 62

Shorter if N can be set by the caller, instead of having to read it as the first line of input.

# width on stdin: 63 chars
read N;while read -n$N r;do [[ $r ]]&&printf %$N's\n' "$r";done
# width as a function arg: 62 chars
f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}

This fails to handle two special cases of input data: empty lines, and \. Otherwise this doesn't subject the input data to word-splitting, pathname expansion, or otherwise treat it as more than just raw data.

read -rn$N, (one extra character) would avoid munging \.

The [[ $r ]]&& is needed because read -n4 can't lookahead to see that the next char is a newline. So it sets r to a 4-char string, and the next read produces a zero-char empty string. Filtering these false newlines without filtering real newlines would require tracking state: whether the previous line was max-length or not. Either more code or a totally different approach would be needed.

[[ $r ]] is shorter than [ -n "$r" ] which is needed to avoid errors if the line starts with -z foo, or is * or something, if you used [ $r ].

Justication happens with the standard printf "%4s" format string.

Test with

f(){ while read -n$1 r;do [[ $r ]]&&printf %$1s\\n "$r";done;}; (echo 4; echo -e "*"; cat /tmp/lines) | f 4