Уникальное имя файла для различных файлов

В комментарии Вы спросили следующее:

Существует ли способ сделать это циклом только через файлы, которые были в той области (не, каждый файл в настоящее время открывается)?

Я не думаю, что Vim отслеживает все буферы, к которым ранее получило доступ окно (“область”). Однако Vim является scriptable

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

(Сокращенные) команды:

  • :Hb Перечислите исторические буферы для этого окна.
  • :Hbn[!] [N] Переключитесь на Энный следующий исторический буфер.
    (как :bn, но ограниченный “историческими” буферами текущего окна)
  • :Hbp[!] [N] Переключитесь на Энный предыдущий исторический буфер.
    (как :bp, но ограниченный “историческими” буферами текущего окна)
  • :Hbf [N] (“забудьте”) Удаляют текущий буфер (или буферизуйте номер N) из списка текущего окна исторических буферов.
    Если Вы не переключитесь на другой буфер для того, чтобы оставить и повторно ввести это окно, то текущий буфер будет повторно добавлен к списку исторических буферов.

Следующий код мог быть помещен в Ваш .vimrc или в отдельном файле (например. plugin/buffer-history/buffer-history.vim где-нибудь под одним из Вашего runtimepath каталоги):

augroup UL17179_BufferHistory
    autocmd!
    autocmd BufEnter * call s:RecordBufEnter(0)
    " Grab WinEnter, since BufEnter is not triggered when doing
    " a bare ':split'. This also means that 'forgetting' a buffer is
    " only effective if you switch to another buffer before
    " switching away from the window.
    autocmd WinEnter * call s:RecordBufEnter(1)
augroup END

function! s:EnsureBufferHistory()
    if ! exists('w:BufferHistory')
        let w:BufferHistory = []
    endif
    return w:BufferHistory
endfunction

function! s:RecordBufEnter(w)
    let l = s:EnsureBufferHistory()
    let b = winbufnr(0)
    let i = index(l, b)
    if i >= 0
        unlet l[i]
    endif
    let l += [b]
    redraw
endfunction

function! s:ForgetBuffer(...)
    let l = s:EnsureBufferHistory()
    for b in a:000
        let b = b ? b+0 : winbufnr(0)
        let i = index(l, b)
        if i >= 0
            call remove(l, i)
        else
            try
                echohl WarningMsg
                echomsg 'Buffer' b 'not in history list.'
            finally
                echohl None
            endtry
        endif
    endfor
endfunction

function! s:ShowBuffers()
    let l = s:EnsureBufferHistory()
    for b in l
        echomsg b bufname(b)
    endfor
endfunction

function! s:HistoricalBufferNr(...)
    let  direction = a:0 >= 1 && !a:1 ? -1 : 1
    let move_count = a:0 >= 2 ? max([1, a:2]) : 1

    let current_bn = winbufnr(0)
    let historical_buffers = copy(filter(s:EnsureBufferHistory(),
                \ 'bufexists(v:val)'))
    let i = index(historical_buffers, current_bn)
    if i < 0
        let other_historical_buffers = historical_buffers
    elseif i == 0
        let other_historical_buffers = historical_buffers[1:]
    else
        let other_historical_buffers = historical_buffers[i+1:] +
                    \ historical_buffers[:i-1]
    endif

    if len(other_historical_buffers) <= 0
        try
            echohl ErrorMsg
            echomsg 'This window has no historical buffers!'
        finally
            echohl None
        endtry
        return 0
    endif
    if direction > 0
        let i = (move_count - 1) % len(other_historical_buffers)
    else
        let l = len(other_historical_buffers)
        let i = ((l - 1) * move_count ) % l
    endif
    return other_historical_buffers[i]
endfunction

" If the 1) user does not give a bang and
"        2) we run 'buffer N' (no bang) from inside the function and 
"        3) switching away from the buffer would require a bang,
" then the user will see an ugly 'Error detected while processing
" function' prefix before the usual E37 error message. Hoisting the
" 'buffer N' into the user-defined command means the user will
" just see a normal E37 message.
command! -nargs=0 -count=1 -bang -bar
            \ HistoricalBufferNext
            \ let s:new_bn = s:HistoricalBufferNr(1, )
            \ | if s:new_bn | exe 'buffer' s:new_bn | endif
command! -nargs=0 -count=1 -bang -bar
            \ Hbn
            \ HistoricalBufferNext 
command! -nargs=0 -count=1 -bang -bar
            \ HistoricalBufferPrev
            \ let s:new_bn = s:HistoricalBufferNr(0, )
            \ | if s:new_bn | exe 'buffer' s:new_bn | endif
command! -nargs=0 -count=1 -bang -bar
            \ Hbp
            \ HistoricalBufferPrev 
command! -nargs=* -count=0 -bar
            \ HistoricalBufferForget
            \ call s:ForgetBuffer(, )
command! -nargs=* -count=0 -bar
            \ Hbf
            \ HistoricalBufferForget  
command! -nargs=0 -bar
            \ HistoricalBuffers
            \ call s:ShowBuffers()
command! -nargs=0 -bar
            \ Hb
            \ HistoricalBuffers

3
23.04.2012, 10:58
3 ответа

Эта команда переименует все файлы к md5sum их содержания. Это означает, что файлы с тем же содержанием получат то же имя.

for f in *; do mv $f $(md5sum $f | cut -d " " -f 1); done

Можно заменить md5sum с sha1sum в команде.

Для этой демонстрации я добавил -v кому: mv таким образом, мы видим то, что переименовывается.

$ echo 1 > a
$ echo 2 > b
$ echo 1 > c
$ ls -1
a
b
c
$ for f in *; do mv -v $f $(md5sum $f | cut -d " " -f 1); done
`a' -> `b026324c6904b2a9cb4b88d6d61c81d1'
`b' -> `26ab0db90d72e28ad0ba1e22ee510510'
`c' -> `b026324c6904b2a9cb4b88d6d61c81d1'
$ ls -1
26ab0db90d72e28ad0ba1e22ee510510
b026324c6904b2a9cb4b88d6d61c81d1

Можно также безопасно выполнить эту команду в каталоге, где некоторые файлы объединили имя файла, в то время как другой не имеют.

$ echo 1 > d
$ echo 2 > e
$ ls -1
26ab0db90d72e28ad0ba1e22ee510510
b026324c6904b2a9cb4b88d6d61c81d1
d
e
$ for f in *; do mv -v $f $(md5sum $f | cut -d " " -f 1); done
mv: `26ab0db90d72e28ad0ba1e22ee510510' and `26ab0db90d72e28ad0ba1e22ee510510' are the same file
mv: `b026324c6904b2a9cb4b88d6d61c81d1' and `b026324c6904b2a9cb4b88d6d61c81d1' are the same file
`d' -> `b026324c6904b2a9cb4b88d6d61c81d1'
`e' -> `26ab0db90d72e28ad0ba1e22ee510510'
$ ls -1
26ab0db90d72e28ad0ba1e22ee510510
b026324c6904b2a9cb4b88d6d61c81d1

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

6
27.01.2020, 21:10

Это rename-hash сценарий я использую для переименования файлов к их hashsum, сохраняя расширение неизменным. Берет список файлов, которые будут переименованы как параметры. Использовать -n как первый параметр для пробного прогона.

#!/bin/sh

unset DRY
[ "$1" == "-n" ] && { DRY=1; shift; }

for i in $@; do

if [ -f "$i" ]; then

HASHSUM=$(md5sum "$i" | sed 's/\(..........\).*/\1/')
DIR=$(dirname "$i")
BASE=$(basename "$i")
EXT=$(echo "$BASE" | sed -n 's/[^.]*\(\..*\)/\1/p')
TARGET="$DIR"/"$HASHSUM""$EXT"
if [ "$TARGET" != "$DIR/$BASE" ]; then
   if [ -n "$DRY" ]; then
       echo will rename "$i" to "$TARGET"
   else
       mv "$i" "$TARGET"
   fi
fi

fi

done

Пример:

$ rename-hash -n *
will rename test.pdf to ./f604d0d6ad.pdf
will rename images.tar.gz to ./d41d8cd91b.tar.gz
3
27.01.2020, 21:10

Существуют некоторые утилиты для нахождения дубликатов. Можно использовать, находят и md5sum, но может довольно требоваться много времени.

Я обычно использую fdupes для этого. Если может найти все дубликаты и произвести их имена к stdout. После этого можно проанализировать вывод и переименовать все файлы, как Вы хотите или даже удаляете их.

0
27.01.2020, 21:10

Теги

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