我正在尝试创建自己的程序来执行递归列表:每行对应于单个文件的完整路径。我现在正在处理的棘手部分是:我不希望绑定挂载将我的程序欺骗到列表文件两次。
所以我已经有一个产生正确输出的程序,除非/foo
绑定挂载到/bar
然后我的程序错误列出
/foo/file
/bar/file
我需要程序列出下面的内容(编辑:即使有人要求列出/foo
的内容)
/bar/file
我想到的一种方法是mount | grep bind | awk '{print $1 " " $3}'
,然后将其迭代到输出的每一行sed
,然后sort -u
。
我的问题是如何迭代原始输出(一堆行)和来自mount
(另一堆行)的输出? (或者有更好的方法)这需要是POSIX(编辑:和/bin/sh
一起工作)
答案 0 :(得分:1)
放置'mount | grep bind'命令进入BEGIN块内的AWK并存储数据。 类似的东西:
PROG | awk 'BEGIN{
# Define the data you want to store
# Assign to global arrays
command = "mount | grep bind";
while ((command | getline) > 0) {
count++;
mount[count] = $1;
mountPt[count] = $3
}
}
# Assuming input is line-by-line and that mountPt is the value
# that is undesired
{
replaceLine=0
for (i=1; i<=count; i++) {
idx = index($1, mountPt[i]);
if (idx == 1) {
replaceLine = 1;
break;
}
}
if (replaceLine == 1) {
sub(mountPt[i], mount[i], $1);
}
if (printed[$1] != 1) {
print $1;
}
printed[$1] = 1;
} '
我假设您当前的程序PROG输出到stdout。
答案 1 :(得分:1)
find YourPath -print > YourFiles.txt
mount > Bind.txt
awk 'FNR == NR && $0 ~ /bind/ {
Bind[ $1] = $3
if( ( ThisLevel = split( $3, Unused, "/") - 1 ) > Level) Level = ThisLevel
}
FNR != NR && $0 !~ /^ *$/ {
RealName = $0
for( ThisLevel = Level; ThisLevel > 0; ThisLevel--){
match( $0, "(/[^/]*){" ThisLevel "}" )
UnBind = Bind[ substr( $0, 1, RLENGTH) ]
if( UnBind !~ /^$/) {
RealName = UnBind substr( $0, RLENGTH + 1)
ThisLevel = 0
}
}
if( ! File[ RealName]++) print RealName
}
' Bind.txt YourFiles.txt