From 7addbe6117294920ccc48e58809dd1ffeb9d3dab Mon Sep 17 00:00:00 2001 From: Julien Caillon Date: Tue, 23 Apr 2024 23:41:41 +0200 Subject: [PATCH] :memo: correctly reading the last line of any file --- docs/working-on-bash-scripts.md | 6 +++++- tests.d/1005-lib-io/resources/file-to-read | 2 +- tests.d/1005-lib-io/results.approved.md | 1 - tests.d/1100-self-config/01.self-config.sh | 4 ++-- tests.d/1300-valet-cli/.before-test | 2 +- valet.d/commands.d/self-build.sh | 6 ++++-- valet.d/commands.d/self-release.sh | 4 ++-- valet.d/lib-io | 4 ++-- valet.d/version | 2 +- 9 files changed, 18 insertions(+), 13 deletions(-) diff --git a/docs/working-on-bash-scripts.md b/docs/working-on-bash-scripts.md index 9560941..fc248ae 100644 --- a/docs/working-on-bash-scripts.md +++ b/docs/working-on-bash-scripts.md @@ -112,6 +112,8 @@ IFS='' read -r -d '' myString < file echo "${myString}" ``` +> With this technique, the last line of the file is always read, even if it does not have a trailing newline. + ### Read a file, line by line This example is for the newline (`$'\n'`) delimiter which is the default delimiter of read, but you can specify any delimiter with `IFS=''` + the `-d ''` option. @@ -119,11 +121,13 @@ This example is for the newline (`$'\n'`) delimiter which is the default delimit Do: ```bash -while read -r myString; do +while read -r myString || [[ -n ${myString:-} ]]; do echo "${myString}" done < file ``` +> Note the `|| [[ -n ${myString:-} ]]` which allows to read the last line even if the file does not have a trailing newline. + Or read into an array and then loop through it: ```bash diff --git a/tests.d/1005-lib-io/resources/file-to-read b/tests.d/1005-lib-io/resources/file-to-read index b2d55e0..fd057c4 100644 --- a/tests.d/1005-lib-io/resources/file-to-read +++ b/tests.d/1005-lib-io/resources/file-to-read @@ -21,4 +21,4 @@ The production of meat and other animal derived products places a heavy burden o ## For people -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. +Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. \ No newline at end of file diff --git a/tests.d/1005-lib-io/results.approved.md b/tests.d/1005-lib-io/results.approved.md index 64a240b..41339f4 100644 --- a/tests.d/1005-lib-io/results.approved.md +++ b/tests.d/1005-lib-io/results.approved.md @@ -83,7 +83,6 @@ The production of meat and other animal derived products places a heavy burden o ## For people Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. - ``` ### Testing io::createFilePathIfNeeded diff --git a/tests.d/1100-self-config/01.self-config.sh b/tests.d/1100-self-config/01.self-config.sh index 769f480..52edac3 100644 --- a/tests.d/1100-self-config/01.self-config.sh +++ b/tests.d/1100-self-config/01.self-config.sh @@ -18,7 +18,7 @@ function testSelfConfig() { selfConfig && exitCode=0 || exitCode=$? echo echo "cat \${configFile}" - io::readFile "${configFile}" && echo "${LAST_RETURNED_VALUE}" + io::cat "${configFile}" endTest "Testing selfConfig" ${exitCode} echo "→ selfConfig" @@ -40,7 +40,7 @@ function testSelfConfig() { ) && exitCode=0 || exitCode=$? echo echo "cat \${configFile}" - io::readFile "${configFile}" && echo "${LAST_RETURNED_VALUE}" + io::cat "${configFile}" endTest "Testing selfConfig override export" ${exitCode} VALET_CONFIG_FILE="${originalConfigFile}" diff --git a/tests.d/1300-valet-cli/.before-test b/tests.d/1300-valet-cli/.before-test index 03c645a..d4ea616 100644 --- a/tests.d/1300-valet-cli/.before-test +++ b/tests.d/1300-valet-cli/.before-test @@ -32,7 +32,7 @@ function echoTempFileWithTimeStampSubstitution() { local file="${GLOBAL_TEST_TEMP_FILE}" local line local IFS=$'\n' - while read -rd $'\n' line; do + while read -rd $'\n' line || [[ -n ${line:-} ]]; do line="${line//??:??:??/HH:MM:SS}" line="${line//????-??-??/YYYY:MM:DD}" echo "${line}" diff --git a/valet.d/commands.d/self-build.sh b/valet.d/commands.d/self-build.sh index e64717b..93b5b80 100644 --- a/valet.d/commands.d/self-build.sh +++ b/valet.d/commands.d/self-build.sh @@ -203,10 +203,12 @@ function summarize() { # Bump the valet build version by one patch. function bumpValetBuildVersion() { - local versionFile currentVersion + local versionFile versionFile="${GLOBAL_VALET_HOME}/valet.d/version" - IFS= read -rd '' currentVersion <"${versionFile}" || : + io::readFile "${versionFile}" + local currentVersion="${LAST_RETURNED_VALUE:-0.0.0}" + currentVersion="${currentVersion%%$'\n'*}" string::bumpSemanticVersion "${currentVersion}" "patch" "false" diff --git a/valet.d/commands.d/self-release.sh b/valet.d/commands.d/self-release.sh index a7b687b..8f60086 100644 --- a/valet.d/commands.d/self-release.sh +++ b/valet.d/commands.d/self-release.sh @@ -104,8 +104,8 @@ function createRelease() { fi # read the version from the valet file - local version - IFS= read -rd '' version <"${GLOBAL_VALET_HOME}/valet.d/version" || : + io::readFile "${GLOBAL_VALET_HOME}/valet.d/version" + local version="${LAST_RETURNED_VALUE}" version="${version%%$'\n'*}" log::info "The current version of valet is: ${version}." diff --git a/valet.d/lib-io b/valet.d/lib-io index d81ce9e..9367767 100644 --- a/valet.d/lib-io +++ b/valet.d/lib-io @@ -273,7 +273,7 @@ function io::readFile() { return 0 fi - local IFS= + local IFS='' if [[ "${maxCharacters}" -gt 0 ]]; then read -rd '' -n "${maxCharacters}" LAST_RETURNED_VALUE <"${filePath}" || true else @@ -376,5 +376,5 @@ function io::sleep() { # io::cat "myFile" function io::cat() { io::readFile "${1}" - printf "%s" "${LAST_RETURNED_VALUE}" + echo "${LAST_RETURNED_VALUE}" } \ No newline at end of file diff --git a/valet.d/version b/valet.d/version index ae165b0..7750040 100644 --- a/valet.d/version +++ b/valet.d/version @@ -1 +1 @@ -0.7.146 \ No newline at end of file +0.7.164 \ No newline at end of file