Usando GNUfind
:
find. -type f -mtime +5 \
-regextype egrep -regex '.*[0-9]{4}-[0-9]{2}-[0-9]{2}[^/]*$' \
-delete
La expresión regular coincidirá con cualquier cadena en el nombre base de un nombre de ruta que contenga una fecha en el formulario YYYY-MM-DD
. Tenga en cuenta que también podemos hacer coincidir XXYYYY-MM-DDZZ
donde XX
y ZZ
son algunos otros caracteres.
El [^/]*$
al final asegura que en realidad estamos haciendo coincidir la expresión con el nombre base de la ruta actual, y significa "no /
para el resto de la cadena, por favor".
Usar un patrón comodín de shell en su lugar (más fácil de mantener):
find. -type f -mtime +5 \
-name '*[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]*' \
-delete
Tenga en cuenta que -mtime +5
es para archivos cuya antigüedad como número entero de días es estrictamente mayor que 5, es decir, 6 días o más. Para archivos de 5 días o más, necesitaría -mtime +4
.
{a..c}1 {a..c}2 {a..c}3
Раскрытие фигурных скобок в {a..c}{1..3}
разворачивается слева направо, поэтому сначала вы получаете a{1..3} b{1..3} c{1..3}
, а затем буквы объединяются с числами в a1 a2 a3 b1 b2 b3 c1 c2 c3
. Чтобы получить желаемый порядок, вам придется использовать немного более длинное выражение выше.
Вы могли бы сделать:
$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3
Что затем указывает оболочке оценить:
echo {a..c}1 {a..c}2 {a..c}3
Использование петли:
for n in {1..3}; do printf '%s\n' {a..c}"$n"; done
Это зациклит ваше первое расширение, а затем дополнит каждый символ вторым.
Если вам нужен вывод всего в одну строку, вы можете удалить\n
:
for n in {1..3}; do printf '%s ' {a..c}"$n"; done
Это не даст вам завершающую новую строку, но если вы передаете ее команде или переменной, это не должно быть проблемой.
Один лайнер, который работает в (bash, ksh, zsh)(не все оболочки могут выполнять «расширение скобок» в обратном порядке):
$ echo {3..1}{c..a} | rev
a1 b1 c1 a2 b2 c2 a3 b3 c3
Альтернативой использованию eval
(, которая по-прежнему предназначена для bash, ksh, zsh и может быть более загадочной ), является:
$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3
Чтобы понять, что происходит, замените eval
наecho
:
$ echo echo '{a..c}'{1..3}
echo {a..c}1 {a..c}2 {a..c}3
Команда, выполненная (после расширения eval ), на самом деле echo {a..c}1 {a..c}2 {a..c}3
. Который расширяется по мере того, как вы хотите/нужно.
Существует несколько оболочек без «расширения фигурных скобок», поэтому их невозможно использовать для «всех оболочек». Нам нужен цикл (с завершающим пробелом):
$ for i in 1 2 3; do for j in a b c; do printf "%s%s " "$j" "$i"; done; done; echo
a1 b1 c1 a2 b2 c2 a3 b3 c3
Если вы не должны добавлять пробелы в конце:
s=""
for i in 1 2 3; do
for j in a b c; do
printf "%s%s%s" "$s" "$j" "$i"
s=" "
done
done
echo
Печать
a1 b1 c1 a2 b2 c2 a3 b3 c3
ЕСЛИ вам нужно сделать это для многих значений, нам нужно использовать что-то похожее на раскрытие фигурной скобки для создания списка чисел $(seq 10)
. А так как seq не может сгенерировать список букв, нам нужно преобразовать в ascii сгенерированные числа:
s=""
for i in $(seq 4); do
for j in $(seq 5); do
printf "%s\\$(printf %03o $((96+j)))%s" "$s" "$i"
s=" "
done
done
echo
отпечатки:
a1 b1 c1 d1 e1 a2 b2 c2 d2 e2 a3 b3 c3 d3 e3 a4 b4 c4 d4 e4
В этом конкретном случае я думаю, что вариант, предложенный Стефаном Шазела , является лучшим.
С другой стороны, при расширении более сложных элементов этот параметр плохо масштабируется. Таким образом, вы можете добиться того же:
$ printf '%s\0' {a..c}{1..3} | sort -zk 1.2,1.2 | tr '\0' ' '
, который возвращает:
a1 b1 c1 a2 b2 c2 a3 b3 c3
Выглядит немного запутанно, но теперь у меня есть огромный контроль над порядком, просто изменив два символа в приведенной выше команде; например:
$ echo {a..b}{1..2}{a..b}{1..2}
это расширится до:
a1a1 a1a2 a1b1 a1b2 a2a1 a2a2 a2b1 a2b2 b1a1 b1a2 b1b1 b1b2 b2a1 b2a2 b2b1 b2b2
Предположим, мне нужны все 1
во втором расширении, тогда2
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.2 | tr '\0' ' '
a1a1 a1a2 a1b1 a1b2 b1a1 b1a2 b1b1 b1b2 a2a1 a2a2 a2b1 a2b2 b2a1 b2a2 b2b1 b2b2
Предположим, мне нужны все a
в третьем расширении, тогдаb
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.3,1.3 | tr '\0' ' '
a1a1 a1a2 a2a1 a2a2 b1a1 b1a2 b2a1 b2a2 a1b1 a1b2 a2b1 a2b2 b1b1 b1b2 b2b1 b2b2
Предположим, мне нужны все 1
в четвертом расширении, тогда2
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.4,1.4 | tr '\0' ' '
a1a1 a1b1 a2a1 a2b1 b1a1 b1b1 b2a1 b2b1 a1a2 a1b2 a2a2 a2b2 b1a2 b1b2 b2a2 b2b2
Предположим, мне нужны все 1a
посередине, затем 1b
, затем 2a
, затем2b
:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.3 | tr '\0' ' '
a1a1 a1a2 b1a1 b1a2 a1b1 a1b2 b1b1 b1b2 a2a1 a2a2 b2a1 b2a2 a2b1 a2b2 b2b1 b2b2
Вы даже можете, так же легко, изменить любой порядок в раскрытии выше, просто добавив r
к предыдущей команде; например, последний:
$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -rzk 1.2,1.3 | tr '\0' ' '
b2b2 b2b1 a2b2 a2b1 b2a2 b2a1 a2a2 a2a1 b1b2 b1b1 a1b2 a1b1 b1a2 b1a1 a1a2 a1a1
Примечание _1:обычно, если это окончательное расширение будет использоваться в качестве списка аргументов, конечный пробел не является проблемой; но если вы хотите избавиться от него, вы можете добавить к любой из приведенных выше команд, например| sed 's/ $//'
; или даже | sed 's/ $/\n/'
, чтобы заменить этот завершающий пробел наnewline
Примечание _2:В приведенных выше примерах я использовал подмножества двух элементов (, т.е.:{a,b} и {1,2})просто для простоты в доказательстве концепции :можно использовать подмножества любой конечной длины, и соответствующие команды будут сравнимы.
Выполнено описанным ниже способом
for i in {1..10}; do for j in {a..c}; do echo $j$i; done; done| perl -pne "s/\n/ /g"
выход
a1 b1 c1 a2 b2 c2 a3 b3 c3 a4 b4 c4 a5 b5 c5 a6 b6 c6 a7 b7 c7 a8 b8 c8 a9 b9 c9 a10 b10 c10
Это работает для вашего простого случая и может быть расширено, но это быстро выйдет из-под контроля. Более сложные случаи, для которых это не сработает, легко построить.
Измените порядок раскрытия фигурных скобок, затем поменяйте местами символы:
echo {1..3}{a..c} | sed -E 's/(.)(.)( ?)/\2\1\3/g'
Одним из простых способов может быть использование sort (1.2,1.2 означает, что вы берете один символ во второй позиции и заканчиваете в том же месте ).
$ for i in {a..c}{1..3}; do echo $i; done|sort -n -k1.2,1.2
a1
b1
c1
a2
b2
c2
a3
b3
c3
Если вы хотите, чтобы они были в одной строке, вы можете использовать tr вот так:
$ for i in {a..c}{1..3}; do echo $i; done|sort -n -k1.2,1.2|tr '\n' ' '
a1 b1 c1 a2 b2 c2 a3 b3 c3