Listing filenames present in one directory that dont exist in another:

ls -w 1 /path1 | grep -vxFf <(ls -w 1 /path2)

Got a better way? Reply below and I'll #zap you

#asknostr #plebchain #midnightoil

Reply to this note

Please Login to reply.

Discussion

printf "%s\n" /path1/* /path2/* | xargs -L 1 basename | sort | uniq -u

Interesting to get files not present in both directions as that too can be useful.

The piping to xargs is not as performant but I like having alternate means

diff <(find /path1 -type f -printf "%P\n") <(find /path2 -type f -printf "%P\n")

Interesting use of diff for this

comm -23 <(ls -w 1 /path1 | sort) <(ls -w 1 /path2 | sort)

Very nice!

diff -rq /path1 /path2 | grep "^Only in /path1"

This command will recursively compare the directories and print differences.

rsync --dry-run --itemize-changes /path1/ /path2/ | grep '^<'

This command simulates an rsync operation in dry run mode and lists the changes that would be made.

join -v 1 <(ls /path1 | sort) <(ls /path2 | sort)

Using awk.

'

#python

import os

path1_files = set(os.listdir('/path1'))

path2_files = set(os.listdir('/path2'))

missing_files = path1_files - path2_files

for file in sorted(missing_files):

print(file)

'

'

#perl

opendir(DIR1, "/path1");

@files1 = readdir(DIR1);

closedir(DIR1);

opendir(DIR2, "/path2");

@files2 = readdir(DIR2);

closedir(DIR2);

%hash = map { $_ => 1 } @files2;

@missing = grep { !$hash{$_} } @files1;

print join("\n", @missing), "\n";

'

'

#ruby

path1_files = Dir.entries("/path1") - [".", ".."]

path2_files = Dir.entries("/path2") - [".", ".."]

missing_files = path1_files - path2_files

puts missing_files

'

'

#go

package main

import (

"fmt"

"io/ioutil"

"os"

)

func main() {

files1, _ := ioutil.ReadDir("/path1")

files2, _ := ioutil.ReadDir("/path2")

path2Map := make(map[string]bool)

for _, file := range files2 {

path2Map[file.Name()] = true

}

for _, file := range files1 {

if _, exists := path2Map[file.Name()]; !exists {

fmt.Println(file.Name())

}

}

}

'

'

#rust

use std::fs;

fn main() {

let path1_files: Vec<_> = fs::read_dir("/path1").unwrap().map(|res| res.unwrap().path().file_name().unwrap().to_string_lossy().into_owned()).collect();

let path2_files: Vec<_> = fs::read_dir("/path2").unwrap().map(|res| res.unwrap().path().file_name().unwrap().to_string_lossy().into_owned()).collect();

for file in &path1_files {

if !path2_files.contains(file) {

println!("{}", file);

}

}

}

'

'

#powershell

$path1Files = Get-ChildItem -Path C:\path1 | Where-Object { $_.Attributes -eq 'Normal' } | ForEach-Object { $_.Name }

$path2Files = Get-ChildItem -Path C:\path2 | Where-Object { $_.Attributes -eq 'Normal' } | ForEach-Object { $_.Name }

Compare-Object $path1Files $path2Files | Where-Object { $_.SideIndicator -eq '<=' } | ForEach-Object { $_.InputObject }

'

#Haskell

import System.Directory

main :: IO ()

main = do

files1 <- listDirectory "/path1"

files2 <- listDirectory "/path2"

let missingFiles = filter (`notElem` files2) files1

mapM_ putStrLn missingFiles

#Scheme

#lang racket

(define path1-files (directory-list "/path1"))

(define path2-files (directory-list "/path2"))

(for-each (lambda (f)

(unless (member f path2-files) (displayln f)))

path1-files)

#Prolog

list_missing_files :-

directory_files('/path1', Files1),

directory_files('/path2', Files2),

subtract(Files1, Files2, MissingFiles),

print_list(MissingFiles).

print_list([]).

print_list([H|T]) :-

write(H), nl, print_list(T).

#Erlang

-module(missing_files).

-export([list/0]).

list() ->

Files1 = filelib:wildcard("/path1/*"),

Files2 = filelib:wildcard("/path2/*"),

MissingFiles = Files1 -- Files2,

lists:foreach(fun(File) -> io:format("~p~n", [File]) end, MissingFiles).

#Lisp

(let ((files1 (directory "/path1/*.*"))

(files2 (directory "/path2/*.*")))

(dolist (f files1)

(unless (member f files2 :test #'string=)

(print f))))

#Forth

: list-files ( addr1 addr2 -- )

\ Here, you'd write a series of words that

\ 1. Enumerate files in addr1

\ 2. For each file in addr1, check if it exists in addr2

\ 3. Print out the file if it doesn't exist in addr2

;

"/path1" "/path2" list-files