Что случилось с моим скриптом bash?

Предположим:

перечислить дублирующее имя файла для каждой строки, сопоставляя одно и то же 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

Скрипт оболочки: :

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];

Примечание: вам нужно изменить это в скрипте ( оригинальный подлинник не работает).

-1
задан 21 November 2017 в 12:00

3 ответа

Похоже, вы:

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

Я не собираюсь исправлять код awk. Вместо этого обратите внимание, что вы копируете функциональные возможности команды fdupes. Из manpage:

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.

Я настоятельно рекомендую вам использовать его вместо написания сложных сценариев для этого.

В противном случае устранение проверки размера значительно облегчает поиск duplates:

$ md5sum * | sort -k1,1 | uniq -w32 -D
b1946ac92492d2347c6235b4d2611184  file1
b1946ac92492d2347c6235b4d2611184  file2
b1946ac92492d2347c6235b4d2611184  file3

Все хэши из md5sums имеют ширину 32 символа, поэтому легко сказать print 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 будет печатать все файлы, размеры которых были дублированы.

[d13 ] Теперь просто используйте конвейер 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
0
ответ дан 22 May 2018 в 16:02
  • 1
    Я никогда не замечаю волшебную мощную комбо-комбинацию, как это, я беру этот код из книги Linux Shell Scripting Cookbook, 2nd Edition для упражнений. Из вашего объяснительного объяснения и демонстрации я многому научился, спасибо за ваши усилия. :)) – mipa 21 November 2017 в 15:41

Похоже, вы:

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

Я не собираюсь исправлять код awk. Вместо этого обратите внимание, что вы копируете функциональные возможности команды fdupes. Из manpage:

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.

Я настоятельно рекомендую вам использовать его вместо написания сложных сценариев для этого.

В противном случае устранение проверки размера значительно облегчает поиск duplates:

$ md5sum * | sort -k1,1 | uniq -w32 -D b1946ac92492d2347c6235b4d2611184 file1 b1946ac92492d2347c6235b4d2611184 file2 b1946ac92492d2347c6235b4d2611184 file3

Все хэши из md5sums имеют ширину 32 символа, поэтому легко сказать print 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
0
ответ дан 18 July 2018 в 02:54

Похоже, вы:

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

Я не собираюсь исправлять код awk. Вместо этого обратите внимание, что вы копируете функциональные возможности команды fdupes. Из manpage:

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.

Я настоятельно рекомендую вам использовать его вместо написания сложных сценариев для этого.

В противном случае устранение проверки размера значительно облегчает поиск duplates:

$ md5sum * | sort -k1,1 | uniq -w32 -D b1946ac92492d2347c6235b4d2611184 file1 b1946ac92492d2347c6235b4d2611184 file2 b1946ac92492d2347c6235b4d2611184 file3

Все хэши из md5sums имеют ширину 32 символа, поэтому легко сказать print 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
0
ответ дан 24 July 2018 в 17:41

Другие вопросы по тегам:

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