如何比较Linux中两个ls命令的输出结果?

4
这是一个我无法解决的任务。我有一个包含.h文件的目录和一个包含与.h文件同名的.i文件的目录。我想通过输入一个命令来获取所有未在.i文件中找到的.h文件。这并不是一个难题,我可以用某种编程语言来完成它,但我只是好奇在cmd中它会是什么样子。更具体地说,这是算法:
  • 从ls *.h中获取没有扩展名的文件名
  • 从ls *.i中获取没有扩展名的文件名
  • 进行比较
  • 打印1中所有未在2中出现的名称
祝你好运!

请查看Linux中的sed程序。 - maths-help-seeker
4个回答

7
diff \
  <(ls dir.with.h | sed 's/\.h$//') \
  <(ls dir.with.i | sed 's/\.i$//') \
| grep '$<' \
| cut -c3-

diff <(ls dir.with.h | sed 's/\.h$//') <(ls dir.with.i | sed 's/\.i$//') 执行ls命令,获取两个目录下的文件列表,并去掉文件名的扩展名,然后比较这两个列表。接着,grep '$<'查找只存在于第一个列表中的文件,cut -c3-去掉diff插入的"< "字符。


感谢您的超级快速响应。我测试了一下,结果是: ls: dir.with.i:没有这个文件或目录 ls: dir.with.h:没有这个文件或目录 - zwx
1
我通过对您的建议进行微小修改来解决了这个问题: comm -23 <(ls *.h | sed 's/.h$//') <(ls *.i | sed 's/.i$//') 感谢您的想法 ;) - zwx

0
ls ./dir_h/*.h | sed -r -n  's:.*dir_h/([^.]*).h$:dir_i/\1.i:p' | xargs ls 2>&1 | \
grep "No such file or directory" | awk '{print $4}' | sed -n -r 's:dir_i/([^:]*).*:dir_h/\1:p'

我的测试结果是: 如此 如此 如此 但应该是: hotfloorplan hotspot hotspot-iface npe如上所述。 - zwx

0
ls -1 dir1/*.hh dir2/*.ii | awk -F"/" '{print $NF}' |awk -F"." '{a[$1]++;b[$0]}END{for(i in a)if(a[i]==1 && b[i".hh"]) print i}'

解释:

ls -1 dir1/*.hh dir2/*.ii

以上命令将列出两个目录中所有的*.hh和*.ii文件。

awk -F"/" '{print $NF}'

上面的代码只会打印文件名,不包括文件的完整路径。

awk -F"." '{a[$1]++;b[$0]}END{for(i in a)if(a[i]==1 && b[i".hh"]) print i}'

上面的代码将创建两个关联数组,一个包含文件名,另一个排除扩展名。 如果hh和ii文件都存在,则关联数组中的值为2;如果只有一个文件,则值为1。因此,我们需要值为1且应该是头文件(.hh)的数组项。 这可以通过在END块中使用关联数组b来检查。


抱歉,但它没有起作用。结果是:ls: dir1/.hh: 没有那个文件或目录 ls: dir2/.ii: 没有那个文件或目录。无论如何,这是一个封闭的问题。感谢您的回复 :) - zwx

0
假设bash是您的shell:
for file in $( ls dir_with_h/*.h ); do
    name=${file%\.h};         # trim trailing ".h" file extension
    name=${name#dir_with_h/}; # trim leading folder name
    if [ ! -e dir_with_i/${name}.i ]; then
        echo ${name};
    fi
done

毫无疑问,这可以移植到几乎所有其他的shell。我发现这比其他一些方法更加清晰易懂(尽管这肯定是我的问题),但有点啰嗦。因此,一个shell脚本可能有助于记忆它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接