ডিরেক্টরি 1 তে কিন্তু 2 ফাইলের সাথে তুলনা করুন?


9

আমি তৈরি করতে চাইছে এমন ব্যাশ স্ক্রিপ্ট নিয়ে আমার সমস্যা হচ্ছে

আমি জানি যে ls ডিরেক্টরিতে থাকা ফাইলগুলি তালিকাভুক্ত করবে তবে আমি এটি ডিরেক্টরি 1 তে ডিরেক্টরি 2 তে ডিরেক্টরি 2 তে ডিরেক্টরি তালিকাতে তালিকাবদ্ধ করতে চাই, এবং তারপরে ডিরেক্টরি 1 তে ডিরেক্টরি 2 তে ফাইল তালিকাবদ্ধ করব।

একটি দুর্বল প্রয়াসে, আমি চেষ্টা করেছি:

ls -al | diff directory1 directory2

দ্রুত বুঝতে পারলাম কেন এটি কাজ করে না। কেউ কি মোট ব্যাশ অহেতুক সাহায্য করতে পারে?

উত্তর:


9

দেওয়া বাশ, এটি হিসাবে সবচেয়ে সহজ হতে পারে

$ comm <(ls -a dir1) <(ls -a dir2)

<(command)অভিব্যক্তি রান আদেশ একটি নল উপর এবং একটি পরিপূরক /dev/fdরেফারেন্স:

mress:10018 Z$ echo <(ls)
/dev/fd/11

সুতরাং উপরের কমান্ডটি ls -aপ্রতিটি ডিরেক্টরিতে চালিত হয় এবং তাদের আউটপুটগুলিকে ফাইল আর্গুমেন্ট হিসাবে ফিড দেয় comm, যা 3 টি কলাম, ট্যাব-ইন্ডেন্টযুক্ত: কেবল প্রথমটিতে উভয় এন্ট্রি, দ্বিতীয়টিতে এন্ট্রি দেয়। (এটি যদি উভয়টিতে থাকে তবে এটি কোনও ট্যাব দ্বারা সূক্ষ্ম হয়, যদি এটি কেবল দ্বিতীয়টিতে থাকে তবে এটি 2 টি ট্যাব দ্বারা ইন্ডেন্ট করা হয়) আপনি কলামগুলিও সংখ্যা অনুসারে দমন করতে পারেন: comm -1 foo barদুটি ফাইলের লাইন এবং দ্বিতীয় ফাইলের লাইনগুলি প্রদর্শন করে, একক ট্যাব দ্বারা পরবর্তীটি ইন্টেন্টেড । (এটি সর্বাধিক সাধারণভাবে আপনি যে কলামটি চান সেগুলি ব্যতীত সকলকে দমন করার মাধ্যমে ব্যবহৃত হয়: comm -13 foo barকেবলমাত্র সাধারণ লাইনগুলি দেখায়))

প্রদত্ত যে আপনি প্রথম ডিরেক্টরিতে চান তাদের অনুবাদ করুন

$ comm -23 <(ls -a dir1) <(ls -a dir2)

আপনার যদি উপস্থিত থাকে কিনা তার চেয়ে বেশি প্রয়োজন হয় তবে ব্যবহার করুন diff -r, যা কেবলমাত্র ফাইলগুলির জন্য আলাদা এবং কেবল এক বা অন্যটিতে পাওয়া ফাইলগুলির জন্য এক-লাইন বার্তা দেয়।


1
lsসাদা স্থান, ট্যাবস, লাইনফিডস, ব্যাকস্পেস এবং ফাইলনামে যেমন সমস্ত সমস্যা নিয়ে আসবে।
ব্যবহারকারী অজানা

1
একমাত্র এটিই নতুন লাইনের বিষয়গুলিকে বিভ্রান্ত করবে এবং আমি যুক্তি দিয়েছি যে সেক্ষেত্রে আপনার যেভাবেই সমস্যা রয়েছে। :) আপনি যদি ভৌতিক, ব্যবহার করুন ls -b
গাইকোসর

সন্ধানের সাথে নয়, আমিও না?
ব্যবহারকারী অজানা

আপনি কীসের সাথে আহ্বান করছেন তার উপর নির্ভর করে find। তবে আমার প্রধান অভিযোগটি findহ'ল এটি একটি খুব ভারী স্লেজহ্যামার যা সাধারণত একটি ছোট ছোট উড়াল at
জিকোসৌর

ধন্যবাদ! এটি কাজ করে তবে আমি কি 'কম' ব্যবহার না করে ফাইল বিতে থাকা সামগ্রীগুলি আউটপুট পেতে পারি?
soju

4

এবং এখানে একটি খাঁটি লিপি। এগুলি হ'ল ডিরেক্টরি এবং ক:

find a b
a
a/a
a/b
a/c
a/f
a/f/h
a/f/i
b
b/b
b/c
b/d
b/f
b/f/g
b/f/h

আদেশটি এখানে:

cd a
find ./ -exec test ! -e ../b/{} ";" -print 

আউটপুট:

./a
./f/i

ফাইলগুলির জন্য a এবং b কে অদলবদল করুন তবে খ-এ নয়। দ্য ! একটি অবহেলা। -আরক্ষার জন্য পরীক্ষা। প্রসায়: "ইন ../b তে পাওয়া ফাইলটি না থাকলে পরীক্ষা করুন"।

দ্রষ্টব্য: 'এ' ছাড়াই নাম পেতে আপনাকে প্রথমে ডুব দিতে হবে। দ্বিতীয় তুলনার জন্য আপনাকে সিডি করতে হবে ../b


1

আপনি যদি কোনও গ্রাফিকাল সরঞ্জাম পছন্দ করেন তবে ব্যবহার করুন

xxdiff dir1 dir2 

আপনার প্রথমে এটি ইনস্টল করার প্রয়োজন হতে পারে। অনুরূপ প্রোগ্রাম হয়

gtkdiff
tkdiff

মধ্যরাতের কমান্ডারের একটি compare directoriesকমান্ড বিল্ড ইন রয়েছে, যা আপনি যদি সাবডিয়ারদের কাছে না যান তবে দুর্দান্ত কাজ করে।


1
না, আমি কোনও গ্রাফিকাল সরঞ্জাম খুঁজছি না, যদিও ধন্যবাদ!
soju

1

আপনি অবহেলিত joinকমান্ড ব্যবহার করতে পারেন । এখানে দুটি উদাহরণ ডিরেক্টরি, ডি 1 / এবং ডি 2 / এর জন্য কিছু সেটআপ রয়েছে যার প্রতিটির ডিরেক্টরিতে অনন্য নামের কিছু ফাইল রয়েছে এবং কিছু ডিরেক্টরি অন্য ডিরেক্টরিতে সাধারণ রয়েছে। এটি কেবলমাত্র একটি উদাহরণ, তাই আমি একা-অক্ষরের ফাইলের নামগুলি এক বা অন্যের কাছে অনন্য, এবং ফাইলের নামগুলি সাধারণভাবে চিত্রিত করতে ব্যবহার করি।

# set up for example
mkdir d1 d2
for name in a  b  c  d  e  f  g  h
do
    touch d1/$name
done
for name in e f g h i j k l
do
    touch d2/$name
done

ls -1 d1 > d1.out   # That's "minus one" not "minus ell"
ls -1 d2 > d2.out
join d1.out d2.out       # files common to both d1/ and d2/
join -v 1 d1.out d2.out  # files only in directory d1/
join -v 2 d1.out d2.out  # files only in directory d2/

আমার জন্য, এটি এই জাতীয় ফাইলগুলি দেখায়:

 5:51PM 100 % join d1.out d2.out
e
f
g
h
 5:51PM 101 % join -v 1 d1.out d2.out
a
b
c
d
 5:52PM 102 % join -v 2 d1.out d2.out
i
j
k
l

আপডেট: আপনি প্রকৃত জীবনে বিভিন্ন জিনিস সাদা বাক্সে স্থান দেওয়ার জন্য করতে চান, joinকোন লাইন একক এবং কোন লাইনগুলি সাধারণ তা নির্ধারণ করার জন্য প্রথম ক্ষেত্রটি "হোয়াইটস্পেস দ্বারা বিস্মৃত" ব্যবহার করে।


আপনার প্রোগ্রামটি "d2 / f" নামে একটি ফাইল দিয়ে পরীক্ষা করা উচিত। থাম্বের বিধি: স্ক্রিপ্টগুলিতে প্রায় কখনও ls ব্যবহার করবেন না।
ব্যবহারকারী অজানা

আপনি কি কিছুটা স্পষ্ট করে বলতে পারেন? ডি 2 / এর কি কেবল একটি ফাইল, ডি 2 / এফ থাকা উচিত? কারণ আমি এটি চেষ্টা করেছি এবং এটি প্রত্যাশার মতো কাজ করে।
ব্রুস এডিগার

আমি মনে করি যে তিনি ফাইলের নামগুলি নিয়ে শঙ্কিত যা স্পেস অন্তর্ভুক্ত করে (বা ট্যাবগুলি, যেহেতু উভয়ই যোগ দেওয়ার জন্য ডিফল্ট ইনপুট ফিল্ড ডিলিমিটার )। হতে পারে join -t ''(কোনও সীমানা ছাড়াই) এই ক্ষেত্রে সহায়তা করবে।
ক্রিস জনসন

হ্যাঁ, তা কিন্তু d2/fনয় d2/f । ফাইলের নামগুলিতে ট্যাব এবং নিউলাইনগুলি বিরল, তবে অনুমোদিত।
ব্যবহারকারী অজানা

0

আপনি এটি ব্যবহার করতে পারেন findএবং awkএটি সমাধান করতে পারেন ।

নিম্নলিখিত লেআউট সহ:

$ mkdir a b a/1 b/1 b/2 a/3
$ touch a/f1 b/f1 a/f2 b/f3

প্রথম অংশ:

$ find a b -mindepth 1 -maxdepth 1 -type d | \
    awk -F/ ' { if (!w[$1]) w[$1]=++i; if (w[$1]>1) b[$2]=1; else a[$2]=1; }
          END { for (x in a) if (!b[x]) print x }'
3

অংশ দুই:

$ find b a -mindepth 1 -maxdepth 1 -type f | \
    awk -F/ ' { if (!w[$1]) w[$1]=++i; if (w[$1]>1) b[$2]=1; else a[$2]=1; }
          END { for (x in a) if (!b[x]) print x }'
f3

এটি একটি commসমাধানের সাথে তুলনা করে :

$ comm -23 <(ls a) <(ls b)    
3
f2
$ comm -13 <(ls a) <(ls b)
2
f3

এবং একটি joinসমাধান:

$ join -v1 <(ls a) <(ls b)
3
f2
$ join -v2 <(ls a) <(ls b)
2
f3

0

আমার ফাংশন ব্যবহার করুন:

setColors ()
{
# http://wiki.bash-hackers.org/scripting/terminalcodes
set -a
which printf >/dev/null 2>&1 && print=printf || print=print # Mandriva doesn't know about printf

hide='eval tput civis'
show='eval tput cnorm'
CLS=$(tput clear)
bel=$(tput bel)

case ${UNAME} in
AIX)
# text / foreground
N=$(${print} '\033[1;30m')
n=$(${print} '\033[0;30m')
R=$(${print} '\033[1;31m')
r=$(${print} '\033[0;31m')
G=$(${print} '\033[1;32m')
g=$(${print} '\033[0;32m')
Y=$(${print} '\033[1;33m')
y=$(${print} '\033[0;33m')
B=$(${print} '\033[1;34m')
b=$(${print} '\033[0;34m')
M=$(${print} '\033[1;35m')
m=$(${print} '\033[0;35m')
C=$(${print} '\033[1;36m')
c=$(${print} '\033[0;36m')
W=$(${print} '\033[1;37m')
w=$(${print} '\033[0;37m')
END=$(${print} '\033[0m')

# background
RN=$(${print} '\033[6;40m')
Rn=$(${print} '\033[40m')
RR=$(${print} '\033[6;41m')
Rr=$(${print} '\033[41m')
RG=$(${print} '\033[6;42m')
Rg=$(${print} '\033[42m')
RY=$(${print} '\033[6;43m')
Ry=$(${print} '\033[43m')
RB=$(${print} '\033[6;44m')
Rb=$(${print} '\033[44m')
RM=$(${print} '\033[6;45m')
Rm=$(${print} '\033[45m')
RC=$(${print} '\033[6;46m')
Rc=$(${print} '\033[46m')
RW=$(${print} '\033[6;47m')
Rw=$(${print} '\033[47m')

HIGH=$(tput bold)
SMUL=$(tput smul)
RMUL=$(tput rmul)
BLINK=$(tput blink)
REVERSE=$(tput smso)
REVERSO=$(tput rmso)
;;
*)
# text / foreground
n=$(tput setaf 0)
r=$(tput setaf 1)
g=$(tput setaf 2)
y=$(tput setaf 3)
b=$(tput setaf 4)
m=$(tput setaf 5)
c=$(tput setaf 6)
w=$(tput setaf 7)
N=$(tput setaf 8)
R=$(tput setaf 9)
G=$(tput setaf 10)
Y=$(tput setaf 11)
B=$(tput setaf 12)
M=$(tput setaf 13)
C=$(tput setaf 14)
W=$(tput setaf 15)
END=$(tput sgr0)

HIGH=$(tput bold)
SMUL=$(tput smul)
RMUL=$(tput rmul)
BLINK=$(tput blink)
REVERSE=$(tput smso)
REVERSO=$(tput rmso)

# background
Rn=$(tput setab 0)
Rr=$(tput setab 1)
Rg=$(tput setab 2)
Ry=$(tput setab 3)
Rb=$(tput setab 4)
Rm=$(tput setab 5)
Rc=$(tput setab 6)
Rw=$(tput setab 7)
RN=$(tput setab 8)
RR=$(tput setab 9)
RG=$(tput setab 10)
RY=$(tput setab 11)
RB=$(tput setab 12)
RM=$(tput setab 13)
RC=$(tput setab 14)
RW=$(tput setab 15)
;;
esac

BLUEf="${B}"
BLUE="${b}"
REDf="${R}"
RED="${r}"
GREENf="${G}"
GREEN="${g}"
YELLOWf="${Y}"
YELLOW="${y}"
MANGENTAf="${M}"
MANGENTA="${m}"
WHITEf="${W}"
WHITE="${w}"
CYANf="${C}"
CYAN="${c}"

OK="${RG}${n}OK${END}"
KO="${RR}${n}KO${END}"
NA="${N}NA${END}"

COLORIZE='eval sed -e "s/{END}/${END}/g" -e "s/{HIGH}/${HIGH}/g" -e "s/{SMUL}/${SMUL}/g" -e "s/{RMUL}/${RMUL}/g" -e "s/{BLINK}/${BLINK}/g" -e "s/{REVERSE}/${REVERSE}/g" -e "s/{REVERSO}/${REVERSO}/g"'
LOWS=' -e "s/{n}/${n}/g" -e "s/{r}/${r}/g" -e "s/{g}/${g}/g" -e "s/{y}/${y}/g" -e "s/{b}/${b}/g" -e "s/{m}/${m}/g" -e "s/{c}/${c}/g" -e "s/{w}/${w}/g"'
HIGHS=' -e "s/{N}/${N}/g" -e "s/{R}/${R}/g" -e "s/{G}/${G}/g" -e "s/{Y}/${Y}/g" -e "s/{B}/${B}/g" -e "s/{M}/${M}/g" -e "s/{C}/${C}/g" -e "s/{W}/${W}/g"'
REVLOWS=' -e "s/{Rn}/${Rn}/g" -e "s/{Rr}/${Rr}/g" -e "s/{Rg}/${Rg}/g" -e "s/{Ry}/${Ry}/g" -e "s/{Rb}/${Rb}/g" -e "s/{Rm}/${Rm}/g" -e "s/{Rc}/${Rc}/g" -e "s/{Rw}/${Rw}/g"'
REVHIGHS=' -e "s/{RN}/${RN}/g" -e "s/{RR}/${RR}/g" -e "s/{RG}/${RG}/g" -e "s/{RY}/${RY}/g" -e "s/{RB}/${RB}/g" -e "s/{RM}/${RM}/g" -e "s/{RC}/${RC}/g" -e "s/{RW}/${RW}/g"'
# COLORIZE Usage:
# command |${COLORIZE} ${LOWS} ${HIGHS} ${REVLOWS} ${REVHIGHS}
}

# diffDir shows diff content between two dirs
diffDir()
{
(($# < 2)) && echo "${W}diffDir ${C}<leftDir> <rightDir> ${c}[[[${C}miss|diff|same|all*${c}] [${C}uniq${c}]] [${C}resolv${c}]]${END}" && return 99
local showWhat=all
local UNIQ=false
local RESOLV=false
local uniqNames="cat"
local resolvPaths="cat"
local rightDirContent=/tmp/diffDir.$$.tmp

local leftDir=$1
local rightDir=$2
case $3 in
mis*) showWhat=miss ;;
dif*|siz*) showWhat=diff ;;
sam*) showWhat=same ;;
*)  showWhat=all ;;
esac
UNIQ=${4:+true}
RESOLV=${5:+true}

[ "$4" == "uniq" ] && uniqNames="awk '/~/ {n=split(\$2,libname,\".\");print libname[1]}'|sort|uniq"
[ "$5" == "resolv" ] && resolvPaths='while read _lib;do /bin/ls ${leftDir}/${_lib}.*;done'

ls -lqF ${rightDir}| awk 'NR>1 {if ($(NF-1) == "->") {printf "%s %s->%s\n",$5,$(NF-2),$NF} else {print $5,$NF}}' | sort -k 2 >${rightDirContent}
ls -lqF ${leftDir}| awk 'NR>1 {if ($(NF-1) == "->") {printf "%s %s->%s\n",$5,$(NF-2),$NF} else {print $5,$NF}}' | sort -k 2 | join -a1 -a2 -1 2 -2 2 -o 1.2,1.1,2.1,2.2 -e 0 - ${rightDirContent} |\
awk -v leftDir=${leftDir} -v rightDir=${rightDir} -v showWhat=${showWhat} '
function commas(d) {
  # http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_65.html
  d = d ""
  gsub(",","",d)
  point = index(d,".") - 1
  if (point < 0) point = length(d)
  while (point > 3) {
    point -= 3
    d = substr(d,1,point)","substr(d,point + 1)
  }
  return d
}
BEGIN {i=1;leftWidth=20;rightWidth=20;totalSizeLeft=0;totalSizeRight=0;sep="----------------------------------------------------------------"}
{
leftColor[i]="{w}";sign[i]="="
if ($2==$3) {if (showWhat!="all" && showWhat!="same") {next} else {leftColor[i]="{N}"}} else {leftColor[i]="{y}";sign[i]="~"}
if ($1 ~ "->") {leftColor[i]="{c}"}
leftName[i]=$1;leftSize[i]=$2;rightSize[i]=$3;rightName[i]=$4
middleColor[i]=leftColor[i]
if (leftName[i]=="0") {leftSize[i]="";leftName[i]="";middleColor[i]="{w}";sign[i]="#"} else {totalLeft++;totalSizeLeft+=leftSize[i]}
if (rightName[i]=="0") {rightSize[i]="";rightName[i]="";leftColor[i]=middleColor[i]="{w}";sign[i]="#"} else {totalRight++;totalSizeRight+=rightSize[i]}
if (showWhat=="same" && sign[i]!="=") {next}
if (showWhat=="miss" && sign[i]!="#") {next}
if (showWhat=="diff" && sign[i]!="~") {next}
if (length($1) > leftWidth) {leftWidth=length($1)}
if (length($4) > rightWidth) {rightWidth=length($4)}
if (leftName[i] ~ "->") {middleColor[i]="{c}"}
i++
}
END {
if (i==1) {print "identical"} else {
printf "%s %."leftWidth"s %.14s : %.14s %."rightWidth"s\n","{c}",sep,sep,sep,sep
printf "%s %"leftWidth"s %14s : %14s %-"rightWidth"s\n","{c}",leftDir,"","",rightDir
for (n=1; n<i; n++) {
  printf "%s %"leftWidth"s %14s %s%s %-14s %-"rightWidth"s\n",leftColor[n],leftName[n],commas(leftSize[n]),middleColor[n],sign[n],commas(rightSize[n]),rightName[n]
}
printf "%s %."leftWidth"s %.14s : %.14s %."rightWidth"s\n","{W}",sep,sep,sep,sep
printf "%s %"leftWidth"s %14s : %-14s %-"rightWidth"s{END}\n","{W}","total : "totalLeft,commas(totalSizeLeft),commas(totalSizeRight),totalRight
}
}' |\
${COLORIZE} ${LOWS} ${HIGHS} |\
eval ${uniqNames} |\
eval ${resolvPaths}

rm -f ${rightDirContent}
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.