Unix-Read File逐行。检查另一个文件中是否存在字符串并执行必要的操作

时间:2016-07-28 21:48:39

标签: shell unix scripting

我需要一些帮助。

FILE1.TXT

aaa:/path/to/aaa:777
bob:/path/to/bbb:700
ccc:/path/to/ccc:600

FILE2.TXT

aaa:/path/to/aaa:700
bbb:/path/to/bbb:700
ccc:/path/to/ccc:644

我应该迭代file2.txt,如果在File1.txt中存在aaa,那么我应该比较文件权限。如果两个文件中aaa的文件权限相同,则忽略。

如果它们不同,则在output.txt

中写下它们

所以在上面的案例中

Output.txt的

aaa:/path/to/aaa:700
ccc:/path/to/ccc:644

我如何在unix shell脚本中实现这一点?请建议

2 个答案:

答案 0 :(得分:1)

我同意@Marc的评论,你在此之前要先尝试一下。
但是,当你从未见过这些结构时,很难找到以下答案,所以我给你一些学习的东西。

如果要逐行解析,可以从

开始
while IFS=: read -r file path mode; do
   comparewith=$(grep "^${file}:${path}:" File2.txt | cut -d: -f3)
   # compare and output
done < File1.txt

对于变得非常慢的大文件。 您可以先从File2.txt中过滤要比较的行。 您想要grep字符串,例如aaa:/path/to/aaa:,包括最后一个:。使用cut -d: -f1-2您可能对输入文件没问题,但最好删除最后三个字符: sed 's/...$//' File1.txt
您可以让grep将输出用作包含使用<()的表达式的文件:

grep -f <(sed 's/...$//' File1.txt) File2.txt

当两个文件具有相同的行(您想要跳过)时,您的示例文件不显示这种情况,您需要另一个进程替换才能使其正常工作:

grep -v -f File1.txt <(grep -f <(sed 's/...$//' File1.txt ) File2.txt )

另一个值得尝试的解决方案是使用awk(请参阅What is "NR==FNR" in awk?访问2个文件)。

答案 1 :(得分:0)

comm - compare two sorted files line by line

根据手册,comm -13 <file1> <file2>必须仅打印<file2>唯一的行:

$ ls
File1.txt  File2.txt
$ cat File1.txt 
aaa:/path/to/aaa:777
bbb:/path/to/bbb:700
ccc:/path/to/ccc:600
$ cat File2.txt 
aaa:/path/to/aaa:700
bbb:/path/to/bbb:700
ccc:/path/to/ccc:644
$ comm -13 File1.txt File2.txt 
aaa:/path/to/aaa:700
ccc:/path/to/ccc:644
$ # Nice!

但它不会检查<file1>中与<file2>的相应行“相似”的行。 I. e。如果File1.txt有行BOB:/path/to/BOB:700File2.txtBBB:/path/to/BBB:700,则它将无法正常工作,因为它会打印后者(而您希望不打印)。

如果字符串bbb:/path/to/bbb:700bbb:/another/path/to/bbb:700应该是“相同的”,它也不会做你想要的。