Предположим, чтобы сделать:
дубликат файла списка называет на строку согласно тому же md5sum в текущем каталоге
Сначала установите среду:
echo "hello" > file1; cp file1 file2; cp file2 file3;
Сценарий оболочки:
#!/bin/bash
#FileName: ls_duplicate.sh
## ls file in size-desc order and long listing format and long-iso timestyle
## -rw-rw-r-- 1 ubuntu ubuntu 6 2017-11-21 13:58 file1
## -rw-rw-r-- 1 ubuntu ubuntu 6 2017-11-21 13:58 file2
## -rw-rw-r-- 1 ubuntu ubuntu 5 2017-11-21 13:58 output
find -maxdepth 1 -type f -exec basename {} \; | xargs ls -lS --time-style=long-iso | awk 'BEGIN {
getline;getline;
prev_name=$8; prev_size=$5;
}
{
cur_name=$8;
cur_size=$5;
if (prev_size==cur_size)
{
"md5sum " prev_name | getline;
prev_md5_sum=$1;
"md5sum " cur_name | getline;
cur_md5_sum=$1;
# print(prev_name, prev_md5_sum, cur_name, cur_md5_sum); # debug
##if the two file is same size and same md5sum, then print duplicate file-name
if ( prev_md5_sum==cur_md5_sum ) { print prev_name; print cur_name;}
}
prev_size=cur_size; prev_name=cur_name;
}' | sort -u
Файлы в Текущем direcotry:
file1 file2 file3 ls_duplicate.sh
Запущенный скрипт: ./ls_duplicate.sh
Вывод:
file1 b1946ac92492d2347c6235b4d2611184 file2 b1946ac92492d2347c6235b4d2611184
file2 -rw-rw-r-- file3 b1946ac92492d2347c6235b4d2611184
таким образом, что, происходят здесь -rw-rw-r--
?
хорошо, я решаю это сам вместо использования
"md5sum " prev_name | getline;
prev_md5_sum=$1;
"md5sum " cur_name | getline;
cur_md5_sum=$1;
использование вместо этого
"md5sum " prev_name | getline md5_sum;
split(md5_sum, arr, " ");
prev_md5_sum=arr[1];
"md5sum " cur_name | getline md5_sum;
split(md5_sum, arr, " ");
cur_md5_sum=arr[1];
Примечание: необходимо изменить это в сценарии (исходный сценарий не работал).
Похоже, вы:
Я не собираюсь пытаться исправить код awk , Вместо этого обратите внимание, что вы реплицируете функциональность команды fdupes
. Из справочной страницы :
Searches the given path for duplicate files. Such files are found by
comparing file sizes and MD5 signatures, followed by a byte-by-byte
comparison.
я настоятельно рекомендую вам использовать ее вместо написания сложных сценариев для этого.
В противном случае устранение проверки размера значительно упрощает поиск дубликатов:
$ md5sum * | sort -k1,1 | uniq -w32 -D
b1946ac92492d2347c6235b4d2611184 file1
b1946ac92492d2347c6235b4d2611184 file2
b1946ac92492d2347c6235b4d2611184 file3
Все хеши из md5sums
имеют ширину 32 символа, поэтому легко распечатать uniq
для сравните только эти 32 символа и распечатайте все найденные дубликаты.
Если вам абсолютно необходима проверка размера, то она становится довольно сложной, но все же проще, чем ваш скрипт. find
может печатать файлы разных размеров, поэтому нет необходимости вносить ls
в микс:
find . -maxdepth 1 -type f -printf "%s/%P\n" |
awk -F/ ' # Use / as delimiter, it wont appear in filename
s[$1]++ { # if the file size has appeared before
if (n[$1]) { # if the first name hasnt been printed yet
print n[$1] # print it and delete it
n[$1] = "";
}
print $2; # print filename with duplicated size
next
} {n[$1] = $2} # save filename for each new size encountered'
Эта команда awk напечатает все файлы, размеры которых были дублированы.
Теперь, просто используйте конвейер md5sum | sort | uniq
, упомянутый ранее:
find -maxdepth 1 -type f -printf "%s/%P\n" |
awk -F/ 's[$1]++ {if (n[$1]){print n[$1]} print $2; n[$1] = ""; next} {n[$1] = $2}' |
xargs -d '\n' md5sum |
sort -k1,1 |
uniq -w32 -D