Skip to content

Instantly share code, notes, and snippets.

@vbrozik
Last active September 21, 2023 06:55
Show Gist options
  • Save vbrozik/1f59d4417769033333c663cd254e1684 to your computer and use it in GitHub Desktop.
Save vbrozik/1f59d4417769033333c663cd254e1684 to your computer and use it in GitHub Desktop.
Test file line length limits in a shell in Linux
#!/bin/sh
# test_len.sh
# This script is used to test the maximum line length that can be processed
# using read -r and eval.
# testing line lengths divided by 10:
test_lengths='409 410 900 1800'
# select a line generator:
# line_generator=generate_line
# line_generator=generate_line_with_spaces
line_generator=generate_line_with_quotes
if test "$line_generator" = generate_line_with_quotes ; then
# If set to 1 add quotes around each word in the line to compensate for
# the fact that eval removes quotes around words.
eval_add_quotes=1
fi
tmp_dir=$(mktemp -d)
generate_line_part () {
printf %s "$2"
for i in $(seq 0 $(( $1 - 1 ))) ; do
printf %s $(( i % 10 ))
done
printf %s "$3"
}
generate_line () {
for i in $(seq 0 "$1") ; do
generate_line_part 10 '' ''
done
}
generate_line_with_spaces () {
for i in $(seq 1 "$1") ; do
generate_line_part 9 ' ' ''
done
}
generate_line_with_quotes () {
for i in $(seq 1 "$1") ; do
generate_line_part 7 ' "' '"'
done
}
generate_lines () {
for i in "$@" ; do
"$line_generator" "$i"
echo
done
}
eval_print_line () {
if test "$eval_add_quotes" -eq 1 ; then
eval "printf ' \"%s\"' $1"
else
eval "printf ' %s' $1"
fi
}
get_file_names () {
for i in "$@" ; do
printf '%s/test_len_%s0.txt\n' "$tmp_dir" "$i"
done
}
generate_files () {
cat /dev/null > "$tmp_dir"/test_len_combined.txt
for i in "$@" ; do
file_name=$(get_file_names "$i")
("$line_generator" "$i" ; echo ) > "$file_name"
cat "$file_name" >> "$tmp_dir"/test_len_combined.txt
done
}
get_files () {
for file_name in $(get_file_names "$@") ; do
cat "$file_name"
done
}
cleanup () {
rm -rf "$tmp_dir"
}
printf 'Using %s; example line of 100 characters:\n' "$line_generator"
"$line_generator" 10
printf '\n\n'
trap cleanup EXIT
# shellcheck disable=SC2086 # word splitting is needed for multi-word options
generate_files $test_lengths
# ls -l "$tmp_dir"/
echo "Lengths of generated lines:"
# shellcheck disable=SC2086
# get_files $test_lengths | awk '{print length}'
for file_name in $(get_file_names $test_lengths) ; do
< "$file_name" awk '{print length}'
done
echo "Lengths of these lines read using 'read -r line':"
# shellcheck disable=SC2086
# get_files $test_lengths |
for file_name in $(get_file_names $test_lengths) ; do
while read -r line ; do
printf ' %s' "$line" | awk '{print length}'
done < "$file_name"
done
echo "Lengths of these lines additionally processed using eval:"
# shellcheck disable=SC2086
# get_files $test_lengths |
for file_name in $(get_file_names $test_lengths) ; do
while read -r line ; do
if test "$eval_add_quotes" -eq 1 ; then
eval "printf ' \"%s\"' $line" | awk '{print length}'
else
eval "printf ' %s' $line" | awk '{print length}'
fi
done < "$file_name"
done
echo "Lengths of these lines additionally processed using eval inside a function:"
# shellcheck disable=SC2086
# get_files $test_lengths |
for file_name in $(get_file_names $test_lengths) "$tmp_dir"/test_len_combined.txt ; do
while read -r line ; do
eval_print_line "$line" | awk '{print length}'
done < "$file_name"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment