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