Как найти файл с одинаковым именем, но разным содержимым

Вы можете использовать sedдля создания одной командной строки mvдля каждого mp3 с базовым именем из 7 символов:

$ find. -name "???????.mp3" | sed 's/\(.*\)\(...\)\(...\)\(.\)\(\.mp3\)/mv \1\2\3\4\5 \1\3\5/'

После просмотра вывода вы можете перенаправить его в файл и выполнить.

2
01.05.2020, 06:06
2 ответа

Добро пожаловать, "newuserr"! Я думаю, что основная проблема здесь заключается в попытке загрузить весь файл в переменную оболочки. Во-первых, это не будет хорошо масштабироваться. Во-вторых, сравнение не будет эффективным из-за изменений, сделанных обратными кавычками при чтении файла в оболочку. И, наконец, все пробелы в файле сломают ваш код. Но есть способы обойти все это!:)

Вы можете использовать возвращаемое значение из diffи вообще не читать файлы в оболочке. Вот так:

if diff $i $j; then
     echo $j
fi

Некоторые другие предложения:

  • Рекомендуется использовать [[вместо [для выполнения условий в оболочке. [[лучше справляется с беспорядком.
  • Что за недостающие предметы? Что, если $iили $jбыли пустыми? Тогда оболочка выдаст ошибку в этой строке.Вы можете заставить оболочку сохранить место для отсутствующей переменной, выполнив "$i"или "$j".
  • shellcheck прочитает ваш код и предложит лучшие практики.
  • В руководстве по стилю оболочки google есть много других советов.
0
28.04.2021, 23:16

Вот еще один вариант с использованием findиwhile read loop

#!/usr/bin/env bash

##: Set a trap to clean up temp files.
trap 'rm -rf "$tmpdir"' EXIT

##: Create temp directory using mktemp.
tmpdir=$(mktemp -d) || exit

##: If arguments less than 2
if (( $# < 2 )); then
  printf >&2 "Usage %s dir1 dir2 \n" "${BASH_SOURCE##*/}"
  exit 1
fi

dirA=$1
dirB=$2

##: Loop through the directories
for d in "$dirA" "$dirB"; do
  if  [[ ! -e $d ]]; then  ##: If directory does not exists
    printf >&2 "%s No such file or directory!\n" "$d"
    exit 1
  elif [[ ! -d $d ]]; then  ##: If it is not a directory.
    printf >&2 "%s is not a directory!\n" "$d"
    exit 1
  fi
done

##: If dir1 and dir2 has the same name.
if [[ $dirA = $dirB ]]; then
  printf >&2 "Dir %s and %s are the same directory!\n" "$dirA" "$dirB"
  exit 1
fi

##: Save the list of files in a file using find.
find "$dirA" -type f -print0 > "$tmpdir/$dirA.txt"
find "$dirB" -type f -print0 > "$tmpdir/$dirB.txt"


##: Although awk is best for comparing 2 files I'll leave that to the awk masters.

while IFS= read -ru "$fd" -d '' file1; do  ##: Loop through files of dirB
  while IFS= read -r -d '' file2; do ##: Loop through files of dirA
    if [[ ${file1##*/} = ${file2##*/} ]]; then  ##: If they have the same name
      if ! cmp -s "$file1" "$file2"; then ##: If content are not the same.
        printf 'file %s and %s has the same name but different content\n' "$file1" "$file2"
      else
        printf 'file %s and %s has the same name and same content\n' "$file1" "$file2"
      fi
    fi
  done < "$tmpdir/$dirA.txt"
done {fd}< "$tmpdir/$dirB.txt"
1
28.04.2021, 23:16

Теги

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