In this step, you will add the code to retrieve the file and directory information from the specified directory and format the output in the same way as the ls -lh
command. Follow the steps below to complete this step:
- Use the
ls
command to retrieve the detailed information about the files and directories in the specified directory, and store the output in the ls_output
variable:
## Use the ls command to retrieve detailed information about files and directories, then process the output line by line
ls_output=$(ls -l --time-style="+%b %d %Y %H:%M" "$1" | tail -n +2)
- Add a
while
loop to process each line of the ls_output
and extract the necessary information:
## Process each line of the ls output
while IFS= read -r line; do
## Remove trailing whitespace from each line
line=$(echo "$line" | sed 's/[[:space:]]*$//')
## Parse each field of the line
permissions=$(echo "$line" | awk '{print $1}')
link_count=$(echo "$line" | awk '{print $2}')
owner=$(echo "$line" | awk '{print $3}')
size=$(echo "$line" | awk '{print $5}')
month=$(echo "$line" | awk '{print $6}')
day=$(echo "$line" | awk '{print $7}')
year=$(echo "$line" | awk '{print $8}')
time=$(echo "$line" | awk '{print $9}')
name=$(echo "$line" | awk '{print $10}')
- Add code to format the file size for better readability:
## Format the file size for better readability
if [[ $size =~ ^[0-9]+$ ]]; then
## If the size is a number, format it
if ((size < 1024)); then
size_formatted="${size}B"
elif ((size < 1024 ** 2)); then
size_formatted="$(printf "%.1f" $(echo "scale=2; $size / 1024" | bc))K"
elif ((size < 1024 ** 3)); then
size_formatted="$(printf "%.1f" $(echo "scale=2; $size / (1024**2)" | bc))M"
else
size_formatted="$(printf "%.1f" $(echo "scale=2; $size / (1024**3)" | bc))G"
fi
else
## If the size cannot be parsed as a number, keep it as is
size_formatted="$size"
fi
- Add code to determine the appropriate date format based on the file's modification time:
current_year=$(date +"%Y")
## Extract year, month, and day from the modified date
file_year=$(echo "$year" | cut -d' ' -f3)
file_month=$(echo "$month" | cut -d' ' -f1)
file_day=$(echo "$day" | cut -d' ' -f1)
## Convert leading zero in month to decimal format
file_month=$(echo "$file_month" | sed 's/^0//')
## Get the timestamp of the file's last modification
file_modified=$(date -d "$month $day $year" +"%s")
## Get the timestamp of 6 months ago
six_months_ago=$(date -d "6 months ago" +"%s")
## Calculate the difference in seconds between the current time and the file's last modification
time_diff=$(($(date +"%s") - file_modified))
if ((file_year == current_year)); then
## If the file's year is the same as the current year
if ((time_diff >= six_months_ago)); then
## More than 6 months ago, display the full date: Month Day Year
formatted_date="$month $day $year"
else
## Within the last 6 months, display the date and time: Month Day HH:MM
formatted_date="$month $day $time"
fi
else
## If the file's year is different from the current year, display the full date: Month Day Year
formatted_date="$month $day $year"
fi
- Finally, add the code to output the formatted file information:
## Output format includes customized date formatting based on the condition
printf "%-12s %-5s %-8s %-8s %s %s %-15s %s\n" "$permissions" "$link_count" "$owner" "$size_formatted" "$formatted_date" "$name"
done <<< "$ls_output"
The complete newls.sh
script is now ready. You can save the file and move on to the next step.