pair up files with matching extensions
Let's say I have this list of files:
a.1
a.2 a.3开发者_C百科 b.1 b.2Is there a bash one-liner that could find the one 'a' file for which there is no 'b' with the same extension? (i.e. a.3: no match)
I'm sure I could write a short bash/perl script to do this. But I would like to know if there is any "trick" for this (of course, GNU tools are at my disposal; awk, sed, find ...)You could try this:
ls -1 [ab].* | sort -t . -k 2 | uniq -u -s2
Here is my bash one-liner
for afile in a*; do bfile=${afile/a/b}; test -f $bfile || echo $afile; done
I like the above solution since it only uses bash and no other tools. However, to showcase the power of Unix tools, the next solution uses 4: ls, sed, sort, and uniq:
ls [ab]* | sed 's/b/a/' | sort | uniq -u
If you can use Perl:
perl -le 'for (<a*>) { /(.*)\.(.*)/; print "$1.$2" if !-e "b.$2"}'
bash version 4 has associative arrays, so you can do this:
declare -A a_files
while read -r filename; do
ext="${filename##*.}"
case "${filename%.*}" in
a) a_files[$ext]="$filename" ;;
b) unset a_files[$ext] ;;
esac
done < <(ls [ab].*)
echo "non-matched 'a' files: ${a_files[@]}"
Or, with awk:
ls [ab].* | awk -F. '
$1 == "a" {a_files[$2] = $0}
$1 == "b" {delete a_files[$2]}
END {for (ext in a_files) print a_files[ext]}
'
Ruby(1.9+)
$ ruby -e 'Dir["a.*"].each{|x|puts x if not File.exist? "b."+x.scan(/a\.(\d+)/)[0][0]}'
精彩评论