Давайте поместим это в кросс--платформенную функцию bash:
# Print N most recently modified files in current dir or below
mrf() {
local _n=${1:-3} # Default to 3
case $OSTYPE in
linux*|msys*)
find. -type f -exec stat -c '%X %n' {} \; | sort -nr | awk -v var="${_n}" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done
;;
darwin*)
find. -type f -exec stat -f '%Dm %N' {} \; | sort -nr | awk -v var="${_n}" 'NR==1,NR==var {print $2}' | while read f; do stat -f '%Sm -- %N' $f; done
;;
esac
}
Использование:
$ mrf
Jan 10 11:50:03 2019 --./somefile
Jan 10 11:44:24 2019 --./nested/dir/file.txt
Jan 10 11:40:50 2019 --./anotherfile
$ mrf 5
Jan 10 11:50:03 2019 --./somefile
Jan 10 11:44:24 2019 --./nested/dir/file.txt
Jan 10 11:40:50 2019 --./anotherfile
Jan 10 06:30:22 2019 --./otherdir/yetanotherfile
Jan 09 10:00:00 2019 --./oldfile
Как вы правильно заметили, важную роль здесь играет переменная окруженияIFS
(field splitting ). Обычно IFS
включает символы <space>
, <tab>
и <newline>
. Это означает, что когда для переменной не используются кавычки, интерпретатор оболочки будет разбивать ее на отдельные аргументы по IFS
значениям, когда это возможно (он даже сжимает несколько IFS
символов ).
Итак, в вашей переменной s
всегда есть следующее значение. Остальное зависит от интерпретации.
1<newline>2<newline>3<newline>4
В первом for
оболочка разделяется $s
перед запуском for
и выполняет цикл четыре раза. Для следующего echo
больше нечего разбивать, поэтому каждый элемент печатается на одной строке (, что и делает echo
).
Второй for
будет запущен только один раз для всего значения s
, как указано выше. Что происходит сейчас, так это то, что оболочка разбивает переменную s
на IFS
перед переходом к echo
(, поскольку вx
)нет двойных кавычек. Это означает, что символы <newline>
станут неактуальными, а каждое число — это всего лишь один аргумент. Когда echo
получает несколько аргументов, они печатаются в том же порядке, разделенном пробелами.