dylanaraps / pure-bash-bible

📖 A collection of pure bash alternatives to external processes.
MIT License
36.53k stars 3.28k forks source link

Add get first/latest file in a directory #45

Open vaxul opened 5 years ago

vaxul commented 5 years ago

Hi, first big thanks for the "bible".

I think it might helpful to add more file handling tips like "get filepath from first file in a directory" or "get the filepath for the last modified file in a directory".

Would someone mind to add good solutions to these?

Best regards

ghost commented 3 years ago
first_file() {
# Usage: first_file [DIR]
local "list" "file"
readarray -t list < <( printf -- '%s\n' "${1:-"${PWD}"}/"* )
for file in "${list[@]}"; do
  if [[ -f "${file}" ]]; then
    printf -- '%s\n' "${file}"
    return 0
  fi
done
return 1
}
last_file() {
# Usage: last_file [DIR]
local "list" "file" "list_files" "max"
readarray -t list < <( printf -- '%s\n' "${1:-"${PWD}"}/"* )
for file in "${list[@]}"; do
  if [[ -f "${file}" ]]; then
    list_files+=( "${file}" )
  fi
done
max="${#list_files[@]}"
((max--))
if [[ -n "${list_files[$max]}" ]]; then
  printf -- '%s\n' "${list_files[$max]}"
else
  return 1
fi
}
first_mdate_file() {
# Usage: first_mdate_file [DIR]
local "list" "file" "list_files" "num" "old_file"
readarray -t list < <( printf -- '%s\n' "${1:-"${PWD}"}/"* )
for file in "${list[@]}"; do
  if [[ -f "${file}" ]]; then
    list_files+=( "${file}" )
  fi
done
num=1
for file in "${list_files[@]}"; do
  if [[ "${file}" -nt "${old_file:-"${list_files[$num]}"}" ]]; then
    old_file="${file}"
  fi
  ((num++))
done
if [[ -n "${old_file:-"${list_files[0]}"}" ]]; then
  printf -- '%s\n' "${old_file:-"${list_files[0]}"}"
else
  return 1
fi
}
last_mdate_file() {
# Usage: last_mdate_file [DIR]
local "list" "file" "list_files" "num" "old_file"
readarray -t list < <( printf -- '%s\n' "${1:-"${PWD}"}/"* )
for file in "${list[@]}"; do
  if [[ -f "${file}" ]]; then
    list_files+=( "${file}" )
  fi
done
num=1
for file in "${list_files[@]}"; do
  if [[ "${file}" -ot "${old_file:-"${list_files[$num]}"}" ]]; then
    old_file="${file}"
  fi
  ((num++))
done
if [[ -n "${old_file:-"${list_files[0]}"}" ]]; then
  printf -- '%s\n' "${old_file:-"${list_files[0]}"}"
else
  return 1
fi
}
Artoria2e5 commented 1 year ago

What's with the printf-readarray?

list=( "${1:-"${PWD}"}/"* )

works as well and is not fragile to newlines.


Regarding "last modified file", I doubt that's possible. There seems to be no way to replace stat.