Используйте yes >> foo
вместо yes > foo
и отдельно : >foo
для очистки файла
yes >> foo
вызывают read
для открытия foo
с O_APPEND
. Это заставляет смещение файла позиционироваться в конец файла перед каждой записью.
Итак, yes
записывает в файл foo
, причем каждая запись приводит к позиционированию указателя файла в конец foo
. Тем временем : > foo
усекает файл до 0 байт. Теперь следующая запись yes
, из-за перестановки указателя файла в "конце" нулевого байта foo
, вызванной O_APPEND
, начинается с начала нулевого байта foo
(IFS=$'\n'; set -f; your_program $(ls -tr))
Предполагается, что имена файлов не содержат символов новой строки.
Пример:
% touch 'a b'
% touch 'c d'
% touch '*'
% (IFS=$'\n'; set -f; printf '%s\n' $(ls -tr))
e f
a b
c d
*
Вариант для стандартной оболочки, которая не поддерживает $'...'
строки:
(IFS='
' ; set -f; your_program $(ls -tr))
Простая оболочка Python, которая будет работать даже с именами файлов, содержащими символы новой строки. Использование может быть this_wrapper your_program *
.
#! /usr/bin/python
import os
import sys
sys.argv[2:] = sorted(sys.argv[2:], key=os.path.getmtime)
os.execvp(sys.argv[1], sys.argv[1:])
Если у вас достаточно обновленные версии утилит GNU с -по -даты, вы можете настроить их на обработку данных с завершением NULL -. Это позволяет создавать конвейеры, на которые не влияют пробелы или символы новой строки в самих данных.
Мой тестовый инструмент — это быстрый скрипт под названием/tmp/args
:
#!/bin/bash
echo "This is args with $# value(s)"
for f in "$@"; do echo "> $f <"; done
Вот как вы можете передать ему серию имен файлов в командной строке, отсортированных по времени последнего изменения файла:
find -type f -printf "%T@ %p\0" | sort -zn | sed -z 's/^[0-9.]* //' | xargs -0 /tmp/args
Команда find
ставит перед каждым именем файла/пути представление в долях секунды даты/времени последнего изменения. Это обрабатывается sort
в порядке от самого низкого (самого старого )до самого высокого (самого нового ). sed
удаляет начальное число, которое мы только что использовали для сортировки, и результирующий набор имен файлов передается в xargs
. Замените %p
на %P
, если вы предпочитаете опускать начальный ./
в именах файлов.
Пример данных
# "c d" contains a space; "e f" contains a newline; "h" has leading whitespace
touch a 'e
f' g ' h ' 'c d' b
Пример результата
This is args with 6 value(s)
>./a <
>./e
f <
>./g <
>./ h <
>./c d <
>./b <
Bash еще не позволяет легко сортировать файлы по времени модификации , поэтому вот обязательный ответ, основанный на zsh -. Вам не нужно переключаться на zsh в качестве оболочки для входа в систему, чтобы использовать ее функции.
Здесь я настроил функцию-оболочку, которая принимает один или два аргумента; первый аргумент - это программа для выполнения (, например.myprogram
); второй необязательный аргумент — это каталог, содержащий файлы, которые вы хотите передать программе. Если вы не укажете второй аргумент, по умолчанию используется текущий каталог.
zeio() {
# Zsh-based Execute with files In Order
[ -d "${2:-.}" ] || return
zsh -c "$1 \"${2:-.}\"/*(.om)"
}
Назовите это как хотите, конечно. После быстрой проверки -второго аргумента (еще раз, по умолчанию .
, текущий каталог ),мы вызываем zsh с одной строкой в двойных -кавычках, которая содержит программу и некоторые начальные аргументы (аргумент #1 )и каталог (аргумент #2 )— по умолчанию .
— с расширением подстановочного знака/шаблона, которое имеет два «квалификатора подстановки» в конце круглых скобок:
.
--должны быть обычные файлы (не каталоги или символические ссылки и т. д.)om
--o
rder (сортировать )результирующий список по времени модификации, сначала самые последние Именно этот квалификатор om
glob делает здесь всю реальную работу.
Вот несколько примеров прогонов; myprog
— это простой сценарий оболочки для демонстрации аргументов, которые он получает, чтобы:
#!/bin/sh
for arg do
printf 'Arg: ->%s<-\n' "$arg"
done
и go.sh
— это файл, в котором я сохранил функцию. Остальная часть структуры каталогов:
$ tree.
.
├── dir1
│ ├── 203142
│ ├── 203143
│ └── 203144
├── dir3
│ ├── first\012filename
│ ├── this is 3rd
│ └── this is second
├── dir two
│ ├── 203225
│ ├── 203226
│ └── 203227
├── go.sh
└── myprog
... где я создал наборы из трех файлов в каждом подкаталоге в указанной последовательности; Я ожидаю увидеть их в том же порядке при выполнении функции. Имя первого файла в каталоге dir3 содержит новую строку, представленную tree
с \012
. Результаты:
$ zeio./myprog
Arg: ->./myprog<-
Arg: ->./go.sh<-
$ zeio./myprog dir1
Arg: ->dir1/203142<-
Arg: ->dir1/203143<-
Arg: ->dir1/203144<-
$ zeio./myprog "dir two"
Arg: ->dir two/203225<-
Arg: ->dir two/203226<-
Arg: ->dir two/203227<-
$ zeio./myprog dir3
Arg: ->dir3/first
filename<-
Arg: ->dir3/this is second<-
Arg: ->dir3/this is 3rd<-