Переименовывать файлы в зависимости от их ранжированного номера?

Взгляните на этот ответ:Как прозрачный SOCKS-прокси узнает, какой IP-адрес назначения использовать?

Цитата:

iptables перезаписывает исходный адрес назначения, но запоминает старый. Затем код приложения может получить его, запросив специальную опцию сокета SO_ORIGINAL_DST.

2
29.01.2020, 07:33
3 ответа

Я покажу вам, как я подойду к этой проблеме шаг за шагом. Во-первых, давайте создадим несколько тестовых данных:

mkdir /tmp/blah && cd /tmp/blah
for f in 1 90 $RANDOM $RANDOM $RANDOM; do touch PIC-$f; done
ls

Файлы должны быть отсортированы по именам, но мы хотим, чтобы они были отсортированы по номерам. В этом может помочь команда sort:

ls | sort -V

-Vозначает «Сортировка по версиям», что подходит для вашего случая. Другие варианты см. в man sort.

Теперь о переименовании. Есть множество способов сделать это, но я пройдусь по выходным данным нашего отсортированного списка. Нам понадобится переменная и цикл:

counter=1 ls PIC-* | sort -V | while read fname; do
    echo mv -i "$fname" NEWPIC-$counter
    let counter+=1
done

Здесь происходит многое, поэтому я объясню подробнее -, начиная с безопасности. Прежде всего, СДЕЛАЙТЕ РЕЗЕРВНУЮ КОПИИ СВОИХ ФАЙЛОВ , прежде чем двигаться дальше -циклы могут очень легко пойти не так, как надо, и стать причиной плохого дня. Вот команда для резервного копирования всего:

mkdir backup; cp PIC* backup

Если мы выполним этот цикл неправильно, мы можем создать беспорядок, поэтому я хотел бы посмотреть, что произойдет, прежде чем запускать его. Обратите внимание на echo? Это распечатает предполагаемые команды вместо их запуска. Вы можете либо удалить echo, либо просто скопировать -и вставить вывод, чтобы запустить команду «по-настоящему»

.

Затем я запустил mv -iдля переименования. Это подскажет, собираюсь ли я что-то перезаписать -, в этот момент все в любом случае стало грушевидным, но, по крайней мере, я буду знать.

В-третьих, обратите внимание, что я переименовываю с PIC-xxxна NEWPIC-xxx. Это действительно важно , потому что я могу случайно переименовать PIC -3 вместо PIC -2 в некоторых случаях (, например. если есть ПОС -2.5 почему то ). Мы можем очистить часть NEWпозже.

Кроме того, я начинаю команду с counter=1 ls | sort -V |.... Установив переменную в команде, я избегаю «странного» поведения, когда я забываю установить ее между тестовыми запусками -, где имена файлов назначения начинаются с NEWPIC-6или чего-то еще вместо NEWPIC-1. Это одна из тех привычек, которые приобретаются после нескольких ошибок :)

.

Теперь о самой петле.

  • while read fnameговорит: «Каждый раз, когда вы видите строку ввода, поместите строку в переменную fnameи запустите следующую часть
  • do.. doneокружает код, который вы хотите запустить для каждой строки
  • echo mv -i "$fname" NEWPIC-$counterраспечатывает команду, которую вы хотите выполнить
  • let counter+=1увеличивает вашу переменную счетчика. Если вы забудете об этом, у вас останется один файл с именем NEWPIC-1, а все остальные файлы исчезнут. Вот почему у нас есть резервные копии:)

Наконец, вот небольшой трюк, чтобы удалить это NEWиз начала имени файла:

for fname in NEWPIC-*; do echo mv $fname ${fname#NEW}; done

Как и прежде, удалите echo, когда результат вас устроит.

1
28.04.2021, 23:25

Этот аннотированный сценарий оболочки может делать то, что вам может понадобиться. Точка с запятой означает последовательное выполнение команд, вертикальная черта означает конвейер, знак решетки начинает комментарии, пара «do -done» — это цикл, заключенный в «пока»

n=1            ; # initialize counter
ls             | # list current working directory
sort -V        | # sort (thanks to dwurf for the flag, but this isn't in POSIX standard yet)
while read f   ; do
mv "$f" PIC-$n ; # rename file 
n=$((n+1))     ; # counter increment. 
done
1
28.04.2021, 23:25

Использование оболочки zsh:

tmpdir=$(mktemp -d)

n=1
for name in PIC-*(.n); do
    mv $name $tmpdir/PIC-$(( n++ ))
done

mv $tmpdir/PIC-*.
rmdir $tmpdir

Это перемещает+переименовывает все обычные файлы, чьи имена соответствуют PIC-*в текущем каталоге, во временный каталог. Файлы перемещаются в отсортированном числовом порядке на основе числа в имени файла (, это то, что делает nв квалификаторе (.n)glob; .выбирает только обычные файлы ). Для каждого файла файл переименовывается в PIC-n, где n— счетчик.

После перемещения и переименования всех файлов они перемещаются обратно в текущий каталог, а временный каталог удаляется.

Использование временного каталога в качестве промежуточной области позволяет избежать конфликтов имен.

Если файлов несколько тысяч, то второй mvможет потребоваться выполнить в цикле, чтобы избежать ошибки «слишком длинный список аргументов»:

# first loop as before, then...

for name in $tmpdir/PIC-*; do
    mv $name.
done

rmdir $tmpdir

Выполнение операций в «обратном порядке» дополнительно даст вам резервную копию файлов с их оригинальными именами во временном каталоге, если вы cpфайл вместо mvих в конце:

tmpdir=$(mktemp -d)

mv PIC-*(.) $tmpdir

n=1
for name in $tmpdir/PIC-*(n); do
    # change "mv" to "cp" (and remove "rmdir" below)
    # to leave a copy in the temporary directory
    mv $name PIC-$(( n++ ))
done

rmdir $tmpdir
1
28.04.2021, 23:25

Теги

Похожие вопросы