Как случайным образом перемешать имена файлов в каталоге

Немного поздно на вечеринку, но я застрял на том же препятствии. Так как я это проработал, я подумал, что поделюсь своими выводами, поскольку все остальные сообщения по этой теме ясны как грязь.

Хотя NetworkManager может видеть устройство, он не знает каких-либо подключений , поддерживаемых устройством. В отличие от Wi-Fi, мы не можем просто сканировать, чтобы составить список доступных подключений. Нам нужно добавить один.

Перед созданием подключения убедитесь, что NetworkManager не препятствует управлению устройством. Это по умолчанию происходит на сервере Ubuntu, чтобы предотвратить захват NetworkManager существующего законного устаревшего соединения (см. Объяснение разработчика Ubuntu здесь ).

Вы можете убедиться, что устройство неуправляемо, когда nmcli device показывает неуправляемый статус вашего устройства, а противоположное - отключено . В этом случае переходите к следующему абзацу.

Чтобы NetworkManager на сервере Ubuntu обрабатывал соединение, скопируйте файл /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf в / etc / NetworkManager /conf.d/10-globally-managed-devices.conf , затем отредактируйте его: измените строку, начинающуюся с unmanaged-device , добавив тип gsm в список исключений:

unmanaged-devices=*,except:type:wifi,except:type:wwan,except:type:gsm

Не забудьте проверить обновления для исходный файл / usr / lib при обновлении NetworkManager.

Создание соединения

Для начала мы создаем новое соединение, названное по вашему желанию, с помощью команды (с соответствующим именем / s) edit , например:

sudo nmcli connection edit type gsm con-name "My GPRS Connection"

Используйте sudo , если вы не хотите разочаровываться при попытке сохранить соединение.

Конечно, если вы не используете GSM, вы можете изменить параметр типа на другой протокол, поддерживаемый NetworkManager.

Теперь вы войдете в режим редактирования. Большинство необходимых вам настроек заполняются автоматически. Вы можете увидеть все текущие настройки с помощью команды print :

nmcli> print
===============================================================================
                Connection profile details (My GPRS Connection)
===============================================================================
connection.id:                          My GPRS Connection
connection.uuid:                        27b012ca-453f-482f-bc0e-c81bbab07310
connection.interface-name:              --
connection.type:                        gsm
connection.autoconnect:                 yes
connection.timestamp:                   0
connection.read-only:                   no
connection.permissions:                 
connection.zone:                        --
connection.master:                      --
connection.slave-type:                  --
connection.secondaries:                 
connection.gateway-ping-timeout:        0
-------------------------------------------------------------------------------
ipv4.method:                            auto
ipv4.dns:                               
ipv4.dns-search:                        
ipv4.addresses:                         
ipv4.routes:                            
ipv4.ignore-auto-routes:                no
ipv4.ignore-auto-dns:                   no
ipv4.dhcp-client-id:                    --
ipv4.dhcp-send-hostname:                yes
ipv4.dhcp-hostname:                     --
ipv4.never-default:                     no
ipv4.may-fail:                          yes
-------------------------------------------------------------------------------
ipv6.method:                            auto
ipv6.dns:                               
ipv6.dns-search:                        
ipv6.addresses:                         
ipv6.routes:                            
ipv6.ignore-auto-routes:                no
ipv6.ignore-auto-dns:                   no
ipv6.never-default:                     no
ipv6.may-fail:                          yes
ipv6.ip6-privacy:                       -1 (unknown)
ipv6.dhcp-hostname:                     --
-------------------------------------------------------------------------------
gsm.number:                             *99#
gsm.username:                           --
gsm.password:                           --
gsm.password-flags:                     0 (none)
gsm.apn:                                --
gsm.network-id:                         --
gsm.network-type:                       -1
gsm.allowed-bands:                      1 (any)
gsm.pin:                                --
gsm.pin-flags:                          0 (none)
gsm.home-only:                          no
-------------------------------------------------------------------------------

Введите help , чтобы увидеть полный список команд.

Единственное, что вам, вероятно, потребуется отредактировать, - это APN вашей сети. Это можно сделать с помощью set gsm.apn , где APN будет иметь вид epc.t-mobile.com , оптовая торговля или vzwinternet. для Verizon.

Вы также можете ограничить подключение к определенному интерфейсу. Это не рекомендуется, особенно для последовательных подключений, когда имя устройства может легко измениться. Если вы хотите, вы можете, например, сделать set connection.interface-name ttyS4 .

Если вы работаете как root, теперь вы можете сохранить свое соединение.

nmcli> save

Вот и все.Если вам нужно вернуться, чтобы отредактировать соединение, используйте nmcli c отредактируйте «Мое соединение GPRS» или напрямую отредактируйте файл конфигурации. В системах на основе Debian вы найдете его в / etc / NetworkManager / system-connections / , в Redhat он будет в / etc / sysconfig / network-scripts / . Эти файлы кажутся передаваемыми из системы в систему - UUID в основном случайный.

Подключение к нашему новому соединению

Теперь вы сможете подключиться к

sudo nmcli device connect 

. Если все пойдет хорошо, NetworkManager автоматически выберет «Мое соединение GPRS». Если нет,

sudo nmcli connection up "My GPRS Connection" ifname 

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

Прокомментируйте, если вам нужна дополнительная информация.

0
14.03.2019, 19:13
5 ответов

Вот один из них, использующий shufиз GNU coreutils:

paste <(printf "%s\n" *) <(printf "%s\n" * | shuf) |
  while IFS=$'\t' read -r from to; do mv -- "$from" "$to.new"; done

for f in *.new; do mv -- "$f" "${f%.new}"; done 

printf "%s\n" *создает список имен файлов, shufперемешивает их. pasteобъединяет два списка так, чтобы в одном столбце был список имен файлов по порядку, а в другом — в перемешанном порядке. (Вы можете создавать списки во временных файлах, если не хотите использовать подстановку процессов , как это сделано выше; также замените IFS=$'\t'на IFS=$(printf '\t'), если ваша оболочка не поддерживает $''.)

Затем это просто передается в цикл while read, и мы переименовываем файлы на основе списка, добавляя суффикс, чтобы не перезаписывать старые файлы. Второй цикл просто удаляет суффиксы.

Вышеприведенное предполагает, что имена файлов не содержат табуляции или новой строки.

(Вы можете реализовать алгоритм тасования вручную в оболочке, но я думаю, что это немного запутает.)

5
28.01.2020, 02:18

Сzsh:

zmodload zsh/files
rand() REPLY=$RANDOM
autoload zargs zmv

files=(*.ext)

# shuffle the list by using our custom "rand" order function
new_files=(*.ext(o+rand))

# append a ".new" suffix
new_files=($^new_files.new)

# rename files
zargs -l2 -- ${files:^new_files} -- mv --

# remove the.new extension once all the files are renamed
zmv '(*.ext).new' '$1'

Та же идея, что и у @ilkkachu, но не делается предположений о том, какие символы могут содержать имена файлов, и не требуется никаких внешних утилит (zsh/filesсодержит встроенную mvкоманду ).

1
28.01.2020, 02:18

Следуя этой идее символической ссылки ctrl -alt -delor , используя shufиз GNU coreutils (этот код также использует readlink -fиз GNU coreutils, чтобы получить абсолютный путь к данному файлу для создания символической ссылки):

#!/bin/sh -e

shufdir=shufdir  # directory at this path will be deleted and recreated

rm -rf "$shufdir"
mkdir -p "$shufdir"

printf '%s\n' "$@" | shuf |
while read -r fname; do
    ln -s "$( readlink -f "$1" )" "$shufdir/$fname"
    shift
done

Сценарий берет имена файлов для перетасовки в своей командной строке. Он создает $shufdirкак подкаталог и продолжает перемешивать все заданные имена файлов. Перемешанные имена файлов затем символически связываются в $shufdirс исходным списком имен файлов, заданным в командной строке.

Код предполагает, что имена путей не содержат новых строк.

Тестирование:

$ ls -l
total 4
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-1
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-10
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-2
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-3
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-4
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-5
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-6
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-7
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-8
-rw-r--r--  1 kk  wheel    0 Mar 14 18:13 file-9
-rw-r--r--  1 kk  wheel  247 Mar 14 18:39 script.sh
$ sh script.sh file-*
$ ls -l shufdir/
total 0
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-1 -> /tmp/shell-yash.WkdNi1GD/file-8
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-10 -> /tmp/shell-yash.WkdNi1GD/file-9
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-2 -> /tmp/shell-yash.WkdNi1GD/file-4
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-3 -> /tmp/shell-yash.WkdNi1GD/file-1
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-4 -> /tmp/shell-yash.WkdNi1GD/file-3
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-5 -> /tmp/shell-yash.WkdNi1GD/file-2
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-6 -> /tmp/shell-yash.WkdNi1GD/file-6
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-7 -> /tmp/shell-yash.WkdNi1GD/file-7
lrwxr-xr-x  1 kk  wheel  31 Mar 14 18:39 file-8 -> /tmp/shell-yash.WkdNi1GD/file-5
lrwxr-xr-x  1 kk  wheel  32 Mar 14 18:39 file-9 -> /tmp/shell-yash.WkdNi1GD/file-10

Ничто не мешает вам копировать или перемещать файлы в новый каталог или использовать жесткие ссылки вместо символических ссылок (если каталог $shufdirнаходится в том же разделе, что и исходные файлы ). Вам просто нужно изменить строку с помощью команды ln -s.

1
28.01.2020, 02:18

Описание

Это не кратчайший путь решения проблемы, но я думаю, что он достаточно прост для понимания.

Рекомендуется создать архив с исходными файлами

tar -cvzf backup.tar.gz file*

чтобы иметь возможность восстановить их после теста (или повторить тест)

tar -xvf backup.tar.gz
  • Я использую несколько временных файлов
  • для создания файла с помощью команд копирования,
  • которые перемешивают имена файлов, "$tmpdir"/tg3.
  • При выполнении этих команд исходные файлы остаются, и
  • Наконец, они перезаписываются.
  • Процесс завершен, временный каталог можно удалить.

Шеллскриптshuffler

#!/bin/bash

tmpdir=$(mktemp -d)
curdir=$(pwd)

ls -1 file* > "$tmpdir"/orig  # list the file names in a file
sed -i -e 's/^/"/' -e 's/$/"/' "$tmpdir"/orig  # quote to allow special chars

cd "$tmpdir"

shuf orig > shuf           # shuffle the names

paste orig shuf > tg1      # build commands...
sed 's/^/cp /' tg1 > tg2   # build commands
sed 's/"$/xtmp"/' tg2 > tg3  # make temporary names
#less tg3
cd "$curdir"

bash "$tmpdir"/tg3         # copy the files to shuffled temporary names
rename -f 's/xtmp$//' file*  # overwrite the original files

rm -r "$tmpdir"

Демонстрационный пример

  • Создать/выбрать каталог

  • Создайте тестовые файлы с содержимым, соответствующим именам файлов

    for ((i=1;i<100;i++));do echo $i>file_$i;done
    
  • Сохраните файлы в tarball

    tar -cvzf backup.tar.gz file*
    
  • Скопируйте шелл-скрипт отсюда в текстовый редактор и сохраните его под именем shufflerв том же каталоге.

  • Сделать шеллскрипт исполняемым

    chmod +x shuffler
    
  • Сделай это

    ./shuffler
    

Теперь вы можете проверить, действительно ли файлы перемешаны, с помощью следующей командной строки (, подходящей только для этого конкретного тестового примера)

$ for ((i=1;i<100;i++));do echo -n "file_$i: ";j=$(cat file_$i);if [ "$i" == "$j" ]; then echo "$j same";else echo "$j";fi;done
file_1: 98
file_2: 45
file_3: 1
file_4: 5
file_5: 93
file_6: 31
file_7: 52
file_8: 84
file_9: 57
file_10: 44
file_11: 2
file_12: 92
file_13: 32
file_14: 12
file_15: 38
file_16: 10
file_17: 64
file_18: 75
file_19: 30
file_20: 68
file_21: 87
file_22: 26
file_23: 36
file_24: 53
file_25: 50
file_26: 51
file_27: 41
file_28: 49
file_29: 21
file_30: 17
file_31: 61
file_32: 73
file_33: 9
file_34: 16
file_35: 55
file_36: 85
file_37: 24
file_38: 83
file_39: 59
file_40: 18
file_41: 20
file_42: 29
file_43: 66
file_44: 82
file_45: 56
file_46: 48
file_47: 71
file_48: 79
file_49: 14
file_50: 86
file_51: 60
file_52: 43
file_53: 22
file_54: 54 same
file_55: 19
file_56: 89
file_57: 28
file_58: 34
file_59: 77
file_60: 88
file_61: 58
file_62: 4
file_63: 96
file_64: 94
file_65: 39
file_66: 69
file_67: 65
file_68: 7
file_69: 90
file_70: 6
file_71: 8
file_72: 47
file_73: 80
file_74: 25
file_75: 97
file_76: 33
file_77: 13
file_78: 15
file_79: 81
file_80: 37
file_81: 42
file_82: 78
file_83: 74
file_84: 3
file_85: 95
file_86: 76
file_87: 40
file_88: 70
file_89: 99
file_90: 27
file_91: 23
file_92: 11
file_93: 91
file_94: 62
file_95: 35
file_96: 63
file_97: 46
file_98: 72
file_99: 67

Прокрутите вниз и обратите внимание, что file_54совпадает. Все остальные файлы имеют новое содержимое. Как и в случае с колодой карт, вы можете перетасовать два или три раза...

Вы также можете сбросить имена файлов из архива и сделать это снова, и каждый раз будут новые результаты, потому что shufполучит новые начальные значения.

1
28.01.2020, 02:18

Вот мой сценарий, использующий алгоритм тасования Фишера-Йейтса:

#!/bin/bash
function swapnames() {
    if [ ! "$2" == "$1" ]; then
        tf=$(mktemp "$1.XXXXXX") && mv "$1" "$tf" && mv "$2" "$1" &&  mv "$tf" "$2" 
    fi
}

function shufflenames() {
    workdir=$1
    pattern=$2
    if [ "$workdir" == "" ]; then workdir="."; fi
    if [ "$pattern" == "" ]; then pattern="*"; fi
    fs=$(printf "%s\n" "$workdir"/$pattern)
    IFS=$'\n' fs=($fs)
    fslen=${#fs[@]}
    ind=1
    while [ $ind -lt $fslen ]; do
        ran=$(($RANDOM%($ind+1)))
        echo swapnames "${fs[$ran]}" "${fs[$ind]}"
        swapnames "${fs[$ran]}" "${fs[$ind]}"
        code=$?
        if [ ! $code -eq 0 ]; then return $code; fi
        ind=$(($ind+1))
    done
}

shufflenames $1 $2

Тогда можно:

./shufflenames picsdir

или

./shufflenames picsdir *.png
0
09.09.2021, 07:29

Теги

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