2016-01-25 2 views
0

Я пытаюсь найти набор файлов с тем же именем между 2 каталогамипоиск файла с использованием Shell Script

**dir1** (/MyFolder/sample/test1)      
file1.txt     
file2.txt     
file3.txt 
file4.txt 

**dir2** (/MyFolder/sample/test2) 
file1.txt 
file4.txt 

Я использую дифф команду следующим образом

diff -sr /MyFolder/sample/test1/ /MyFolder/sample/test2/ | awk -F: '{print $1}' | grep -r ".txt" 

Результат следующий:

Files /MyFolder/sample/test1/file1.txt and /MyFolder/sample/test2/file1.txt are identical 
Files /MyFolder/sample/test1/file4.txt and /MyFolder/sample/test2/file4.txt are identical 

В результате я являюсь oking for - это только имя файла:

file1.txt 
file4.txt 

Любая помощь приветствуется!

+0

'diff' предназначен для сравнения _contents_ файлов, а не _names_ файлов. – e0k

ответ

3

Немного пустячный с Ls & Grep должен работать тоже:

ls dir1 | grep "`ls dir2`" 

Или, если это C Shell:

ls dir1 | grep -E "`ls dir2 | tr '\n' '|'` " 

Как отмечает radical7, первый метод не будет работать в оболочке C, поскольку символы новой строки теряются при переходе к grep. В таких случаях мы могли бы использовать регулярное выражение.

grep -E или просто egrep позволяет нам использовать регулярное выражение вида file1.txt|file2.txt как шаблон.

Также обратите внимание, что пробелы в конце преднамеренно.

+2

Очень круто! Любопытно, что эта форма не работает в оболочках на основе c-shell.Интерполяция строк в оболочках sh основывает (или вставляет - не может сказать) новую строку, в то время как символы новой строки в интерполированной строке удаляются в c-shell (если они когда-либо были там в первую очередь). – radical7

+0

Интересно. Обновлен мой ответ. – loxxy

0

Вот (я надеюсь) простой, легко понять метод с использованием некоторых локальных файлов:

cd /MyFolder/sample 
(cd test1 ; ls -1 *) > test1-files 
(cd test2 ; ls -1 *) > test2-files 
comm -12 test1-files test2-files 

Команда comm будет принимать два файла (который ls делает в данном случае для нас, в противном случае вы должны были бы до sort) и выводит три столбца: строки исключительно в первом файле, строки исключительно во втором файле и соответствующие строки в обоих файлах. Чтобы ограничить вывод на то, что вы просили, команда -12 в команде comm подавляет первые два столбца.

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

(cd test1 ; ls -1 ; cd ../test2 ; ls -1) | sort | uniq -c | grep -v "1 " | awk '{ print $2; }' 

Если вы не знакомы с конструкцией команд-в-скобки, он выполняет файлы подоболочку, объединяющую выход в stdin, который должен быть передан по цепочке трубопроводов.

На самом деле, вы можете вложить команды:

((cd test1 ; ls -1) ; (cd test2 ; ls -1)) | ... 

Примечание здесь существует не cd ../test2, что было в исходном примере. Когда подоболочка выйдет, вы вернетесь в каталог, из которого вы начали.

Смежные вопросы