Skip to main content
deleted 1 character in body
Source Link
Stéphane Chazelas
  • 591.8k
  • 97
  • 1.1k
  • 1.7k

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'

Note that if using zsh, you can just use it'sits e glob qualifier to further qualify the directories (/) with an arbitrary shell expression:

print -rC1 ./**/*(ND/e['[ -f $REPLY/$REPLY:t.md ]'])

Or with a function:

has_md() [ -f $REPLY/$REPLY:t.md ]
print -rC1 ./**/*(ND/+has_md)

(N for nullglob, D for dotglob to not ignore hidden files and dirs)

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'

Note that if using zsh, you can just use it's e glob qualifier to further qualify the directories (/) with an arbitrary shell expression:

print -rC1 ./**/*(ND/e['[ -f $REPLY/$REPLY:t.md ]'])

Or with a function:

has_md() [ -f $REPLY/$REPLY:t.md ]
print -rC1 ./**/*(ND/+has_md)

(N for nullglob, D for dotglob to not ignore hidden files and dirs)

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'

Note that if using zsh, you can just use its e glob qualifier to further qualify the directories (/) with an arbitrary shell expression:

print -rC1 ./**/*(ND/e['[ -f $REPLY/$REPLY:t.md ]'])

Or with a function:

has_md() [ -f $REPLY/$REPLY:t.md ]
print -rC1 ./**/*(ND/+has_md)

(N for nullglob, D for dotglob to not ignore hidden files and dirs)

added 389 characters in body
Source Link
Stéphane Chazelas
  • 591.8k
  • 97
  • 1.1k
  • 1.7k

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'

Note that if using zsh, you can just use it's e glob qualifier to further qualify the directories (/) with an arbitrary shell expression:

print -rC1 ./**/*(ND/e['[ -f $REPLY/$REPLY:t.md ]'])

Or with a function:

has_md() [ -f $REPLY/$REPLY:t.md ]
print -rC1 ./**/*(ND/+has_md)

(N for nullglob, D for dotglob to not ignore hidden files and dirs)

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'

Note that if using zsh, you can just use it's e glob qualifier to further qualify the directories (/) with an arbitrary shell expression:

print -rC1 ./**/*(ND/e['[ -f $REPLY/$REPLY:t.md ]'])

Or with a function:

has_md() [ -f $REPLY/$REPLY:t.md ]
print -rC1 ./**/*(ND/+has_md)

(N for nullglob, D for dotglob to not ignore hidden files and dirs)

Source Link
Stéphane Chazelas
  • 591.8k
  • 97
  • 1.1k
  • 1.7k

Some alternative approaches to be able to run arbitrary shell code instead of just [ -f "$d/${d##*/}.md" ]:

Pass the shell code as the first argument and use eval to interpret it:

FIND(){
    find . -type d -exec sh -c '
        code=$1; shift
        for d do
            eval "$code" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '[ -f "$d/${d##*/}.doc" ]'

Same with an environment variable

FIND(){
    CODE=$1 find . -type d -exec sh -c '
        for d do
            eval "$CODE" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND 'base=${d##*/}; [ -f "$d/$base.md" ] && [ -f "$d/$base.doc" ]'

Of if the shell code to interpret is always going to be [ -f "something" ]:

FIND(){
    FILE_TEST=$1 find . -type d -exec sh -c '
        for d do
            eval "[ -f \"$FILE_TEST\" ]" && printf "%s\n" "$d"
        done' find-sh "$1" {} +
}
FIND '$d/${d##*/}.doc'