如何测试路径是否在文件中列出?
How to test if path is listed in a file?
对于 windows 脚本,我有几乎完全相同的问题 ,但现在我需要在 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/
中的所有文件都应该被忽略。
relPathToFile=${file#$PWD} # remove $PWD from beginning
while read -r excludePath; do
if [[ $relPathToFile == $excludePath/* ]]; then
if [[ -f $cppFile ]]; then
...
fi
done < './Exclude.txt'
您可以使用 readlink -f $some_file_name
获取完整的文件名,然后您可以检查文件是否在列表中。
思路:去掉$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
添加到相对路径以使其成为绝对路径,并查看它们是否是绝对文件路径的前缀。
您可以调用 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
对于 windows 脚本,我有几乎完全相同的问题
我有一个脚本可以递归地查找所有 .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/
中的所有文件都应该被忽略。
relPathToFile=${file#$PWD} # remove $PWD from beginning
while read -r excludePath; do
if [[ $relPathToFile == $excludePath/* ]]; then
if [[ -f $cppFile ]]; then
...
fi
done < './Exclude.txt'
您可以使用 readlink -f $some_file_name
获取完整的文件名,然后您可以检查文件是否在列表中。
思路:去掉$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
添加到相对路径以使其成为绝对路径,并查看它们是否是绝对文件路径的前缀。
您可以调用 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