#bash #shell #command-line
#bash #оболочка #командная строка
Вопрос:
Я использую find . -type d -name "Financials"
для поиска всех каталогов с именем «Финансовые данные» в текущем каталоге. Поскольку я нахожусь на Mac, я могу использовать следующее (которое я нашел из другого вопроса stackoverflow), чтобы найти последний измененный файл в моем текущем каталоге: find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -rn | head -1 | cut -f2- -d" "
. Что я хотел бы сделать, так это найти способ передать результаты первой команды во вторую команду, то есть найти самый последний измененный файл в каждом каталоге «Financials». Есть ли способ сделать это?
Комментарии:
1. Итак, вы знаете
xargs
, так почему бы и нетfind ... | xargs -I{} find {} ... |
?in each "Financials" directory.
означает ли это в каждом отдельно или в каждом все вместе?2. Спасибо, оба ответа приемлемы и помогают мне делать то, что мне нужно.
Ответ №1:
Я думаю, вы могли бы:
find . -type d -name "Financials" -print0 |
xargs -0 -I{} find {} -type f -print0 |
xargs -0 stat -f "%m %N" | sort -rn | head -1 | cut -f2- -d" "
Но если вы хотите отдельно для каждого каталога, то… почему бы просто не выполнить цикл:
find . -type d -name "Financials" |
while IFS= read -r dir; do
echo "newest file in $dir is $(
find "$dir" -type f -print0 |
xargs -0 stat -f "%m %N" | sort -rn | head -1 | cut -f2- -d" "
)"
done
Ответ №2:
Вложите 2-й файл xargs в первый find xargs:
find . -type d -name "Financials" -print0
| xargs -0 sh -c '
for d in "$@"; do
find "$d" -type f -print0
| xargs -0 stat -f "%m %N"
| sort -rn
| head -1
| cut -f2- -d" "
done
' sh
Обратите внимание на завершающую букву «sh» в sh -c '...' sh
— это слово становится «$ 0» внутри сценария оболочки, чтобы цикл for мог перебирать все каталоги.
Ответ №3:
Надежный способ, который также позволит избежать проблем со смешными именами файлов, содержащими специальные символы, — это:
-
найдите все файлы в этом конкретном подкаталоге и извлеките номер индекса и время модификации
$ find . -type f -ipath '*/Financials/*' -printf "%T@ %in"
-
извлеките номер индекса самого молодого файла
$ ... | awk '($1>t){t=$1;i=$2}END{print i}'
-
поиск информации о файле по номеру индекса
$ find . -type f -inum "$inode" '*/Financials/*'
Таким образом, это дает вам:
$ inode="$(find . -type f -ipath '*/Financials/*' -printf "%T@ %in" | awk '($1>t){t=$1;i=$2}END{print i}')"
$ find . -type f -inum "$inode" '*/Financials/*'