В системных вызовах существует на самом деле три градации.
getpid
, gettimeofday
, getuid
или setuid
. Некоторые системные вызовы могут блокироваться или не блокироваться в зависимости от обстоятельств; например, read
никогда блоки, если файл является каналом или другим типом, который поддерживает неблокирующиеся чтения и O_NONBLOCK
флаг установлен.sleep
.read
обращенный блокирующийся дескриптор файла блокируется и так wait
. Различие между “быстрыми” и “медленными” системными вызовами близко к неблокированию по сравнению с блокированием, но на этот раз с точки зрения реализатора ядра. Быстрый syscall является тем, который, как известно, может завершиться, не блокируясь или ожидая. Когда ядро встречается с быстрым syscall, оно знает, что может сразу выполнить syscall и сохранить тот же процесс запланированным. (В некоторых операционных системах с невытесняющей многозадачностью быстрый syscalls может быть неприоритетным; дело обстоит не так в нормальных системах Unix.), С другой стороны, медленный syscall потенциально требует ожидания другой задачи завершиться, таким образом, ядро должно подготовиться приостанавливать обработку вызовов и выполнять другую задачу.
Некоторые случаи являются чем-то вроде серой области. Например, чтение с диска (read
из регулярного файла), обычно рассматривается, не блокируясь, потому что он не ожидает другого процесса; это только ожидает диска, который обычно занимает только немного времени для ответа, но не возьмет навсегда (таким образом, это - случай 2 выше). Но с точки зрения ядра, процесс должен ожидать дискового драйвера для завершения, таким образом, это - определенно медленный syscall.
Хорошо, таким образом, Вы хотите архивировать два iterables, или другими словами Вы хотите единственный цикл, выполняющий итерации по набору строк, с дополнительным счетчиком. Довольно легко реализовать счетчик.
n=0
for x in $commands; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done
Обратите внимание, что это только работает, если ни один из элементов, которых Вы выполняете итерации, не содержит пробела (ни globbing символы). Если Вам разделили объекты новые строки, выключаете globbing и разделяете только на новых строках.
n=0
IFS='
'; set -f
for x in $commands; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done
set +f; unset IFS
Если только необходимо выполнить итерации по данным однажды, цикл вокруг read
(см., Почему while IFS= read
используемый так часто, вместо IFS=; while read..
? для большего количества объяснений).
n=0
while IFS= read -r x; do
mv -- "$x" "$n.jpg"
n=$(($n+1))
done <<EOF
…
EOF
При использовании оболочки, которая имеет массивы (удар, ksh или zsh), сохраните элементы в массиве. В zsh, любом выполнении setopt ksh_arrays
к элементам массива числа от 0, или адаптируют код к нумерации элемента массива, запускающейся в 1.
commands=(
./01/IMG0000.jpg
…
)
n=0
while [[ $n -lt ${#commands} ]]; do
mv -- "${commands[$n]}" "$n.jpg"
done
Если Ваша оболочка bash
, Вы не должны работать seq
программа. Просто используйте
for i in {1..736}
do
Если Вы хотите последовательность с начальными нулями, просто используйте {001..736}
(или даже {0001..0736}
) вместо этого.
Кроме того, если это возможно, попытайтесь не использовать обратные галочки (см. этот вопрос для того, как он может испортить вещи).
Другая вещь, когда Вы хотите воздействовать на ряд файлов, Вы могли бы найти это полезным:
for file in /some/path/*
do
Который будет воздействовать на все файлы (и папки) в каталоге /some/path/
. Для сужения этого к файлам только можно использовать тест как [ -f "$file" ]
, например,
for file in /some/path/*
do
[ -f "$file" ] || continue
(do your stuff here)
Кроме того, конструкция /some/path/*
может быть настроен шаблонами оболочки как /some/path[123]/*
, /some/path[A-Z]/b*[e-g]*
, /some/path{1,5,23}/*
и т.д.
Что касается первой части Вашего вопроса, можно просто использовать вложенный for
(или while
или любой) цикл как это:
for cm in $commands; do
for file in /some/path[ab]{1,4,2}/*.log; do
mv "${file}" "${file//text/replacement}"
done
done
Я не думаю, что можно выполнить итерации по нескольким вещам параллельно в ударе.
Я начал бы i=1
. затем выполните итерации по своему списку файлов и включайте let i=$i+1
в цикле. Также включайте тест для убегания из цикла если $i -ge 736
если Вы хотите выйти из итерации по тому, что Ваш вход после того количества циклов.
i=0
for file in ./{01..10}/*jpg; do
let i=$i+1
mv "$file" "$i-$file"
done
Если бы Вы пытались вполне то после X количества файлов Вы могли бы использовать тест как это:
[[ $i -ge 736 ]] && return || let i=$i+1
удар поддерживает массивы:
http://tldp.org/LDP/abs/html/arrays.html
ИЛИ
COUNT=0
for i in `ls *.txt`
do
COUNT=`expr $COUNT + 1`
mv "$i" "$COUNT-$i"
done
Это переименовало бы файлы a.txt b.txt c.txt к 1-a.txt 2-b.txt 3-c.txt.
ls
как этот! Оболочка globing обработает это правильно, с помощью ls
повредит его!
– Caleb
23.08.2011, 18:16
(( COUNT++ ))
– glenn jackman
23.08.2011, 18:46
ls
.Это не работает. Кроме того, если Вы не работаете на старинных вещах, используйте арифметику оболочки, Вам не нужно expr
больше.
– Gilles 'SO- stop being evil'
24.08.2011, 01:29