如何测试路径是否列在文件中?

时间:2017-01-24 15:18:18

标签: bash shell relative-path

对于Windows脚本,我几乎有完全相同的问题here,但现在我需要在linux中执行相同的操作。

我有一个递归查找所有.h文件的脚本,并检查同一目录中是否有.cpp个文件同名。到目前为止,这有效,但现在我想使用包含应排除的文件夹的Exclude.txt文件。我的问题是$file是完整路径,但在Exclude.txt中,我只想列出相对于$pwd的路径。我怎么能这样做?

#!/bin/bash
for file in $(find ${PWD} -name '*.h'); do 
    fileWithoutPath=$(basename $file)
    fileWithoutExtension=${fileWithoutPath%.*}
    prefix="$(dirname $file)/"
    suffix=".cpp"
    cppFile=$prefix$fileWithoutExtension$suffix

    if ??? path is not listed in ./Exclude.txt  ???   <--- what to put here?
        if [ -f "$cppFile" ]
        then
            echo "FILE EXISTS"
        else 
            echo "FILE DOES NOT EXIST"
        fi
    fi      
done

举个例子:

script is in:         /u/workingDir/
Exclude has a line:   foo

然后应忽略/u/workingDir/foo/中的所有文件。

4 个答案:

答案 0 :(得分:1)

relPathToFile=${file#$PWD}      # remove $PWD from beginning
while read -r excludePath; do
    if [[ $relPathToFile == $excludePath/* ]]; then
        if [[ -f $cppFile ]]; then
            ...
    fi
 done < './Exclude.txt'

答案 1 :(得分:1)

想法:切断$PWD前缀,然后您可以grep获取文件中的结果。

这会将当前目录前缀关闭$filename

stripped_file=${filename##$PWD/}

一个例子:

$ cd /tmp
$ echo $PWD
/tmp
$ filename='/tmp/foo.txt'
$ echo ${filename##$PWD/}
foo.txt

重用此技巧以查看相对路径是否包含剥离的文件名:

if [ "$stripped_file_name" != "${stripped_file_name##$relative_path}" ]; then
   # hey, removing the relative path worked, so the file must be
   # on the relative path; go on.
fi

否则,您可能 $PWD添加到相对路径以使其成为绝对路径,并查看它们是否是绝对文件路径的前缀。

答案 2 :(得分:1)

您可以调用perl one-liner将$prefix的绝对路径转换为相对于$PWD的相对路径(让我们称之为$relPath):

echo "$prefix" #=> /u/workingDir/foo/bar/
relPath=$(perl -e 'use File::Spec; print File::Spec->abs2rel(@ARGV) . "\n"' $prefix $PWD)
echo "$relPath" #=> foo/bar (<-- This is what you'd put into Exclude.txt)

接下来,我们将使用grep检查$relPath中是否列出了Exclude.txt。如果是,我们将忽略该目录,如果不是,那么我们将检查是否存在$cppFile

if ! grep -xqF "$relPath" ./Exclude.txt; then
   # Check for file...
   if [ -f "$cppFile" ]
      ...
   fi
else
   echo "IGNORE $relPath"
fi

答案 3 :(得分:0)

您可以使用readlink -f $some_file_name获取完整的文件名,然后您可以检查文件是否在列表中。