Find only those folders that contain a File with the same name as the FolderUnderstanding the -exec option of `find`Why can't I have a folder and a file with the same name?Find directories that do not contain subdirectoriesHow to find file/directory names that are the same, but with different capitalization/case?Merging folders with practically the same name but different casingDelete directories that contain a certain fileConditional statements: finding folders that don't contain a particular filefind xml file that contain specific tag name and print the words between tag nameFind all files with the same nameUnzip to a folder with the same nameFind directories that do not contain a file in only directories proceeding a specific directory
Do predators tend to have vertical slit pupils versus horizontal for prey animals?
Is there a way to make the "o" keypress of other-window <C-x><C-o> repeatable?
Designing a prison for a telekinetic race
Tabularx with hline and overrightarrow vertical spacing
Starships without computers?
Playing a fast but quiet Alberti bass
Adding things to bunches of things vs multiplication
Earliest evidence of objects intended for future archaeologists?
What happened after the end of the Truman Show?
Atmospheric methane to carbon
Levenshtein Neighbours
Are unaudited server logs admissible in a court of law?
What is "super" in superphosphate?
Does the Temple of the Gods spell nullify critical hits?
Polar contour plot in Mathematica?
Can I check a small array of bools in one go?
Rotate List by K places
Do banks' profitability really suffer under low interest rates
Meaning and structure of headline "Hair it is: A List of ..."
How best to join tables, which have different lengths on the same column values which exist in both tables?
Is there such a thing as too inconvenient?
Why should I pay for an SSL certificate?
How to use source_location in a variadic template function?
What causes burn marks on the air handler in the attic?
Find only those folders that contain a File with the same name as the Folder
Understanding the -exec option of `find`Why can't I have a folder and a file with the same name?Find directories that do not contain subdirectoriesHow to find file/directory names that are the same, but with different capitalization/case?Merging folders with practically the same name but different casingDelete directories that contain a certain fileConditional statements: finding folders that don't contain a particular filefind xml file that contain specific tag name and print the words between tag nameFind all files with the same nameUnzip to a folder with the same nameFind directories that do not contain a file in only directories proceeding a specific directory
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I want to find all subfolders, that contains a markdown file with the same name (and extension .md
).
For example: I want to Find following subfolders:
Apple/Banana/Orange #Apple/Banana/Orange/Orange.md exists
Apple/Banana #Apple/Banana/Banana.md exists
Apple/Banana/Papaya #Apple/Banana/Papaya/Papaya.md exists
- Note: There can be other files or subdirectory in the directory.
Any suggestions?
The solutions to the problem can be tested using the following code:
#!/usr/bin/env bash
# - goal: "Test"
# - author: Nikhil Agarwal
# - date: Wednesday, August 07, 2019
# - status: P T' (P: Prototyping, T: Tested)
# - usage: ./Test.sh
# - include:
# 1.
# - refer:
# 1. [directory - Find only those folders that contain a File with the same name as the Folder - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/534190/find-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder)
# - formatting:
# shellcheck disable=
#clear
main()
TestData
ExpectedOutput
TestFunction "$1:?"Please enter a test number, as the first argument, to be executed!""
TestFunction()
echo "Test Function"
echo "============="
"Test$1"
echo ""
Test1()
echo "Description: Thor"
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Test2() sort
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test3()
echo "Description: Kusalananda2"
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
if [ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]
then
printf "%sn" "$dirpath"
fi
done' sh +
Test4()
echo "Description: steeldriver1"
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
Test5() sort
echo "Observation: $Green:=Pass$Normal:="
Test6() gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test7()
echo "Description: Zach"
#shellcheck disable=2044
for fd in $(find . -type d); do
dir=$fd##*/
if [ -f "$fd/$dir.md" ]; then
ls "$fd/$dir.md"
fi
done
echo "Observation: $Green:=Pass but shows filepath instead of directory$Normal:="
ExpectedOutput()
echo "Expected Output"
echo "==============="
cat << EOT
./GeneratedTest/A
./GeneratedTest/A/AA
./GeneratedTest/B
./GeneratedTest/C/CC1
./GeneratedTest/C/CC2
EOT
TestData()
rm -rf GeneratedTest
mkdir -p GeneratedTest/A/AA
touch GeneratedTest/index.md
touch GeneratedTest/A/A.md
touch GeneratedTest/A/AA/AA.md
mkdir -p GeneratedTest/B
touch GeneratedTest/B/B.md
touch GeneratedTest/B/index.md
mkdir -p GeneratedTest/C/CC1
touch GeneratedTest/C/index.md
touch GeneratedTest/C/CC1/CC1.md
mkdir -p GeneratedTest/C/CC2
touch GeneratedTest/C/CC2/CC2.md
mkdir -p GeneratedTest/C/CC3
touch GeneratedTest/C/CC3/CC.md
mkdir -p GeneratedTest/C/CC4
main "$@"
find directory filenames gnu
add a comment |
I want to find all subfolders, that contains a markdown file with the same name (and extension .md
).
For example: I want to Find following subfolders:
Apple/Banana/Orange #Apple/Banana/Orange/Orange.md exists
Apple/Banana #Apple/Banana/Banana.md exists
Apple/Banana/Papaya #Apple/Banana/Papaya/Papaya.md exists
- Note: There can be other files or subdirectory in the directory.
Any suggestions?
The solutions to the problem can be tested using the following code:
#!/usr/bin/env bash
# - goal: "Test"
# - author: Nikhil Agarwal
# - date: Wednesday, August 07, 2019
# - status: P T' (P: Prototyping, T: Tested)
# - usage: ./Test.sh
# - include:
# 1.
# - refer:
# 1. [directory - Find only those folders that contain a File with the same name as the Folder - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/534190/find-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder)
# - formatting:
# shellcheck disable=
#clear
main()
TestData
ExpectedOutput
TestFunction "$1:?"Please enter a test number, as the first argument, to be executed!""
TestFunction()
echo "Test Function"
echo "============="
"Test$1"
echo ""
Test1()
echo "Description: Thor"
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Test2() sort
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test3()
echo "Description: Kusalananda2"
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
if [ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]
then
printf "%sn" "$dirpath"
fi
done' sh +
Test4()
echo "Description: steeldriver1"
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
Test5() sort
echo "Observation: $Green:=Pass$Normal:="
Test6() gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test7()
echo "Description: Zach"
#shellcheck disable=2044
for fd in $(find . -type d); do
dir=$fd##*/
if [ -f "$fd/$dir.md" ]; then
ls "$fd/$dir.md"
fi
done
echo "Observation: $Green:=Pass but shows filepath instead of directory$Normal:="
ExpectedOutput()
echo "Expected Output"
echo "==============="
cat << EOT
./GeneratedTest/A
./GeneratedTest/A/AA
./GeneratedTest/B
./GeneratedTest/C/CC1
./GeneratedTest/C/CC2
EOT
TestData()
rm -rf GeneratedTest
mkdir -p GeneratedTest/A/AA
touch GeneratedTest/index.md
touch GeneratedTest/A/A.md
touch GeneratedTest/A/AA/AA.md
mkdir -p GeneratedTest/B
touch GeneratedTest/B/B.md
touch GeneratedTest/B/index.md
mkdir -p GeneratedTest/C/CC1
touch GeneratedTest/C/index.md
touch GeneratedTest/C/CC1/CC1.md
mkdir -p GeneratedTest/C/CC2
touch GeneratedTest/C/CC2/CC2.md
mkdir -p GeneratedTest/C/CC3
touch GeneratedTest/C/CC3/CC.md
mkdir -p GeneratedTest/C/CC4
main "$@"
find directory filenames gnu
1
Regarding your final remarks. Note that some answers do different things from others. Mine and Stéphane's for example, interpreted your first "Note" as "if there are other markdown files in the directory whatsoever, don't return that directory" while the others don't (as far as I can see). Apart from that, only you can pick the answer that is most helpful to you. Answers here will continue to receive up and down votes after you have accepted an answer, depending on what other readers find most useful.
– Kusalananda♦
Aug 6 at 18:47
When you say "Folders that contain markdown file whose names are different should not be found," do you mean to exclude directories with both? E.g. if you havefoo/foo.md
andfoo/bar.md
shouldfoo
be included or excluded?
– Kevin
Aug 7 at 20:36
@Kevin In the example that you gave, I had meant to include foo. But unfortunately many people interpreted in the other way and they justified that. So, I thought that I was not clear in communication. So, I accepted answer which did not included foo.
– Nikhil
Aug 7 at 20:56
If you use-printf
with find, you can get whatever part of the match you want, see my edit
– Thor
Aug 8 at 7:26
add a comment |
I want to find all subfolders, that contains a markdown file with the same name (and extension .md
).
For example: I want to Find following subfolders:
Apple/Banana/Orange #Apple/Banana/Orange/Orange.md exists
Apple/Banana #Apple/Banana/Banana.md exists
Apple/Banana/Papaya #Apple/Banana/Papaya/Papaya.md exists
- Note: There can be other files or subdirectory in the directory.
Any suggestions?
The solutions to the problem can be tested using the following code:
#!/usr/bin/env bash
# - goal: "Test"
# - author: Nikhil Agarwal
# - date: Wednesday, August 07, 2019
# - status: P T' (P: Prototyping, T: Tested)
# - usage: ./Test.sh
# - include:
# 1.
# - refer:
# 1. [directory - Find only those folders that contain a File with the same name as the Folder - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/534190/find-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder)
# - formatting:
# shellcheck disable=
#clear
main()
TestData
ExpectedOutput
TestFunction "$1:?"Please enter a test number, as the first argument, to be executed!""
TestFunction()
echo "Test Function"
echo "============="
"Test$1"
echo ""
Test1()
echo "Description: Thor"
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Test2() sort
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test3()
echo "Description: Kusalananda2"
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
if [ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]
then
printf "%sn" "$dirpath"
fi
done' sh +
Test4()
echo "Description: steeldriver1"
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
Test5() sort
echo "Observation: $Green:=Pass$Normal:="
Test6() gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test7()
echo "Description: Zach"
#shellcheck disable=2044
for fd in $(find . -type d); do
dir=$fd##*/
if [ -f "$fd/$dir.md" ]; then
ls "$fd/$dir.md"
fi
done
echo "Observation: $Green:=Pass but shows filepath instead of directory$Normal:="
ExpectedOutput()
echo "Expected Output"
echo "==============="
cat << EOT
./GeneratedTest/A
./GeneratedTest/A/AA
./GeneratedTest/B
./GeneratedTest/C/CC1
./GeneratedTest/C/CC2
EOT
TestData()
rm -rf GeneratedTest
mkdir -p GeneratedTest/A/AA
touch GeneratedTest/index.md
touch GeneratedTest/A/A.md
touch GeneratedTest/A/AA/AA.md
mkdir -p GeneratedTest/B
touch GeneratedTest/B/B.md
touch GeneratedTest/B/index.md
mkdir -p GeneratedTest/C/CC1
touch GeneratedTest/C/index.md
touch GeneratedTest/C/CC1/CC1.md
mkdir -p GeneratedTest/C/CC2
touch GeneratedTest/C/CC2/CC2.md
mkdir -p GeneratedTest/C/CC3
touch GeneratedTest/C/CC3/CC.md
mkdir -p GeneratedTest/C/CC4
main "$@"
find directory filenames gnu
I want to find all subfolders, that contains a markdown file with the same name (and extension .md
).
For example: I want to Find following subfolders:
Apple/Banana/Orange #Apple/Banana/Orange/Orange.md exists
Apple/Banana #Apple/Banana/Banana.md exists
Apple/Banana/Papaya #Apple/Banana/Papaya/Papaya.md exists
- Note: There can be other files or subdirectory in the directory.
Any suggestions?
The solutions to the problem can be tested using the following code:
#!/usr/bin/env bash
# - goal: "Test"
# - author: Nikhil Agarwal
# - date: Wednesday, August 07, 2019
# - status: P T' (P: Prototyping, T: Tested)
# - usage: ./Test.sh
# - include:
# 1.
# - refer:
# 1. [directory - Find only those folders that contain a File with the same name as the Folder - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/534190/find-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder)
# - formatting:
# shellcheck disable=
#clear
main()
TestData
ExpectedOutput
TestFunction "$1:?"Please enter a test number, as the first argument, to be executed!""
TestFunction()
echo "Test Function"
echo "============="
"Test$1"
echo ""
Test1()
echo "Description: Thor"
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Test2() sort
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test3()
echo "Description: Kusalananda2"
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
if [ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]
then
printf "%sn" "$dirpath"
fi
done' sh +
Test4()
echo "Description: steeldriver1"
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
Test5() sort
echo "Observation: $Green:=Pass$Normal:="
Test6() gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
echo "Observation: $Red:=Fails as it ignores B.md$Normal:="
Test7()
echo "Description: Zach"
#shellcheck disable=2044
for fd in $(find . -type d); do
dir=$fd##*/
if [ -f "$fd/$dir.md" ]; then
ls "$fd/$dir.md"
fi
done
echo "Observation: $Green:=Pass but shows filepath instead of directory$Normal:="
ExpectedOutput()
echo "Expected Output"
echo "==============="
cat << EOT
./GeneratedTest/A
./GeneratedTest/A/AA
./GeneratedTest/B
./GeneratedTest/C/CC1
./GeneratedTest/C/CC2
EOT
TestData()
rm -rf GeneratedTest
mkdir -p GeneratedTest/A/AA
touch GeneratedTest/index.md
touch GeneratedTest/A/A.md
touch GeneratedTest/A/AA/AA.md
mkdir -p GeneratedTest/B
touch GeneratedTest/B/B.md
touch GeneratedTest/B/index.md
mkdir -p GeneratedTest/C/CC1
touch GeneratedTest/C/index.md
touch GeneratedTest/C/CC1/CC1.md
mkdir -p GeneratedTest/C/CC2
touch GeneratedTest/C/CC2/CC2.md
mkdir -p GeneratedTest/C/CC3
touch GeneratedTest/C/CC3/CC.md
mkdir -p GeneratedTest/C/CC4
main "$@"
find directory filenames gnu
find directory filenames gnu
edited Aug 7 at 21:26
Nikhil
asked Aug 6 at 16:40
NikhilNikhil
4264 silver badges16 bronze badges
4264 silver badges16 bronze badges
1
Regarding your final remarks. Note that some answers do different things from others. Mine and Stéphane's for example, interpreted your first "Note" as "if there are other markdown files in the directory whatsoever, don't return that directory" while the others don't (as far as I can see). Apart from that, only you can pick the answer that is most helpful to you. Answers here will continue to receive up and down votes after you have accepted an answer, depending on what other readers find most useful.
– Kusalananda♦
Aug 6 at 18:47
When you say "Folders that contain markdown file whose names are different should not be found," do you mean to exclude directories with both? E.g. if you havefoo/foo.md
andfoo/bar.md
shouldfoo
be included or excluded?
– Kevin
Aug 7 at 20:36
@Kevin In the example that you gave, I had meant to include foo. But unfortunately many people interpreted in the other way and they justified that. So, I thought that I was not clear in communication. So, I accepted answer which did not included foo.
– Nikhil
Aug 7 at 20:56
If you use-printf
with find, you can get whatever part of the match you want, see my edit
– Thor
Aug 8 at 7:26
add a comment |
1
Regarding your final remarks. Note that some answers do different things from others. Mine and Stéphane's for example, interpreted your first "Note" as "if there are other markdown files in the directory whatsoever, don't return that directory" while the others don't (as far as I can see). Apart from that, only you can pick the answer that is most helpful to you. Answers here will continue to receive up and down votes after you have accepted an answer, depending on what other readers find most useful.
– Kusalananda♦
Aug 6 at 18:47
When you say "Folders that contain markdown file whose names are different should not be found," do you mean to exclude directories with both? E.g. if you havefoo/foo.md
andfoo/bar.md
shouldfoo
be included or excluded?
– Kevin
Aug 7 at 20:36
@Kevin In the example that you gave, I had meant to include foo. But unfortunately many people interpreted in the other way and they justified that. So, I thought that I was not clear in communication. So, I accepted answer which did not included foo.
– Nikhil
Aug 7 at 20:56
If you use-printf
with find, you can get whatever part of the match you want, see my edit
– Thor
Aug 8 at 7:26
1
1
Regarding your final remarks. Note that some answers do different things from others. Mine and Stéphane's for example, interpreted your first "Note" as "if there are other markdown files in the directory whatsoever, don't return that directory" while the others don't (as far as I can see). Apart from that, only you can pick the answer that is most helpful to you. Answers here will continue to receive up and down votes after you have accepted an answer, depending on what other readers find most useful.
– Kusalananda♦
Aug 6 at 18:47
Regarding your final remarks. Note that some answers do different things from others. Mine and Stéphane's for example, interpreted your first "Note" as "if there are other markdown files in the directory whatsoever, don't return that directory" while the others don't (as far as I can see). Apart from that, only you can pick the answer that is most helpful to you. Answers here will continue to receive up and down votes after you have accepted an answer, depending on what other readers find most useful.
– Kusalananda♦
Aug 6 at 18:47
When you say "Folders that contain markdown file whose names are different should not be found," do you mean to exclude directories with both? E.g. if you have
foo/foo.md
and foo/bar.md
should foo
be included or excluded?– Kevin
Aug 7 at 20:36
When you say "Folders that contain markdown file whose names are different should not be found," do you mean to exclude directories with both? E.g. if you have
foo/foo.md
and foo/bar.md
should foo
be included or excluded?– Kevin
Aug 7 at 20:36
@Kevin In the example that you gave, I had meant to include foo. But unfortunately many people interpreted in the other way and they justified that. So, I thought that I was not clear in communication. So, I accepted answer which did not included foo.
– Nikhil
Aug 7 at 20:56
@Kevin In the example that you gave, I had meant to include foo. But unfortunately many people interpreted in the other way and they justified that. So, I thought that I was not clear in communication. So, I accepted answer which did not included foo.
– Nikhil
Aug 7 at 20:56
If you use
-printf
with find, you can get whatever part of the match you want, see my edit– Thor
Aug 8 at 7:26
If you use
-printf
with find, you can get whatever part of the match you want, see my edit– Thor
Aug 8 at 7:26
add a comment |
6 Answers
6
active
oldest
votes
Assuming your files are sensibly named, i.e. no need for -print0
etc. You can do this with GNU find like this:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Output:
./Apple/Banana/Orange/Orange.md
./Apple/Banana/Papaya/Papaya.md
./Apple/Banana/Banana.md
If you only want the directory name, add a -printf
argument:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$' -printf '%hn'
Output when run on your updated test data:
GeneratedTest/A/AA
GeneratedTest/A
GeneratedTest/C/CC2
GeneratedTest/C/CC1
GeneratedTest/B
Even without GNU find:find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
3
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
1
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't requireprint0
.
– Jim L.
Aug 6 at 20:08
@Thor%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is%h
being used here?
– Nikhil
Aug 8 at 7:48
@Nikhil: Not withfind
, see section 3.2.2.1 in the manual for more details.
– Thor
Aug 8 at 10:22
add a comment |
On a GNU system, you could do something like:
find . -name '*.md' -print0 |
gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
3
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Stéphane, I agree with steeldriver. Do mention the previouszsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.
– Kusalananda♦
Aug 6 at 18:38
1
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
add a comment |
find . -type d -exec sh -c '
dirpath=$1
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]' sh ; -print
The above would find all directories below the current directory (including the current directory) and would execute a short shell script for each.
The shell code would test whether there's a markdown file with the same name as the directory inside the directory, and whether this is the only *.md
name in that directory. If such a file exists and if it's the only *.md
name, the inline shell script exits with a zero exit status. Otherwise it exits with a non-zero exit status (signalling failure).
The set -- "$dirpath"/*.md
bit will set the positional parameters to the list of pathnames matching the pattern (matches any name with a suffix .md
in the directory). We can then use $#
later to see how many matches we got from this.
If the shell script exits successfully, -print
will print the path to the found directory.
Slightly speedier version that uses fewer invocations of the inline script, but that doesn't let you do more with the found pathnames in find
itself (the inline script may be further expanded though):
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] &&
[ "$#" -eq 1 ] &&
printf "%sn" "$dirpath"
done' sh +
The same commands but without caring about whether there are other .md
files in the directories:
find . -type d -exec sh -c '
dirpath=$1
[ -f "$dirpath/$dirpath##*/.md" ]' sh ; -print
find . -type d -exec sh -c '
for dirpath do
[ -f "$dirpath/$dirpath##*/.md" ] &&
printf "%sn" "$dirpath"
done' sh +
See also:
- Understanding the -exec option of `find`
add a comment |
Either
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
or
find . -type d -exec sh -c '
for d do
[ -f "$d/$d##*/.md" ] && printf "%sn" "$d"
done' find-sh +
To avoid running one sh
per file.
The find-sh
is an arbitrary string that becomes the shell's zeroth positional parameter $0
- making it something memorable may help with debugging in case the shell encounters errors (others may suggest using plain sh
or even _
as a default "skip" parameter).
add a comment |
Here's mine. I added some more directories and files to verify. I was also bored, so I added the last modified time and MD5. Maybe you're looking for duplicates.
GREEN='33[0;32m'
RED='33[0;31m'
NC='33[0m'
mkdir -pv Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin
touch Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin/Strawberry,Grape,Raisin.md
for dir in $(find ./ -type d)
do
dirname="$dir##*/"
fname="$dirname.md"
if [ -f "$dir/$fname" ]
then
STAT=$(stat --printf="%y %s" "$dir/$fname")
STAT="$STAT:0:19"
MD5=$(md5sum "$dir/$fname")
MD5="$MD5:0:32"
printf "$GREEN%-60s$NC%-40s%-40sn" "'$dir/$fname' exists" "$STAT" "$MD5"
else
echo -e "$RED'$dir/$fname' doesn't exist$NC"
fi
done
'.//.md' doesn't exist
'./Raisin/Raisin.md' doesn't exist
'./Raisin/Raisin/Raisin.md' exists 2019-08-07 19:54:09 a3085274bf23c52c58dd063faba0c36a
'./Raisin/Nababa/Nababa.md' doesn't exist
'./Raisin/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 3d2eca1d4a3c539527cb956affa8b807
'./Raisin/Grape/Grape.md' exists 2019-08-07 19:54:09 f577b20f93a51286423c1d8973973f01
'./Raisin/DragonFruit/DragonFruit.md' doesn't exist
'./Pear/Pear.md' doesn't exist
'./Pear/Raisin/Raisin.md' exists 2019-08-07 19:54:09 61387f5d87f125923c2962b389b0dd67
'./Pear/Nababa/Nababa.md' doesn't exist
'./Pear/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 02c9e39ba5b77954082a61236f786d34
'./Pear/Grape/Grape.md' exists 2019-08-07 19:54:09 43e85d5651cac069bba8ba36e754079d
'./Pear/DragonFruit/DragonFruit.md' doesn't exist
'./Apple/Apple.md' doesn't exist
'./Apple/Banana/Banana.md' exists 2019-08-07 19:54:09 a605268f3314411ec360d7e0dd234960
'./Apple/Banana/Papaya/Papaya.md' exists 2019-08-07 19:54:09 e759a879942fe986397e52b7ba21a9ff
'./Apple/Banana/Orange/Orange.md' exists 2019-08-07 19:54:09 127618fe9ab73937836b809fa0593572
'./Plaintain/Plaintain.md' doesn't exist
'./Plaintain/Raisin/Raisin.md' exists 2019-08-07 19:54:09 13ed6460f658ca9f7d222ad3d07212a2
'./Plaintain/Nababa/Nababa.md' doesn't exist
'./Plaintain/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 721d7a5a32f3eacf4b199b74d78b91f0
'./Plaintain/Grape/Grape.md' exists 2019-08-07 19:54:09 0bdaff592bbd9e2ed5fac5a992bb3566
'./Plaintain/DragonFruit/DragonFruit.md' doesn't exist
'./Grape/Grape.md' doesn't exist
'./Grape/Raisin/Raisin.md' exists 2019-08-07 19:54:09 aa5d4c970e7b4b6dc35cd16d1863b5bb
'./Grape/Nababa/Nababa.md' doesn't exist
'./Grape/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 8b02f8273bbff1bb3162cb088813e0c9
'./Grape/Grape/Grape.md' exists 2019-08-07 19:54:09 5593d7d6fdcbb48ab5901ba30469bbe8
add a comment |
This would require a bit of logic.
for fd in `find . -type d`; do
dir=$fd##*/
if [ -f $fd/$dir.md ]; then
ls $fd/$dir.md
fi
done
You can also adapt that to fit into a one liner by using code blocks.
EDIT: Bash is hard. basedir
is not a command, dirname
doesn't do what I thought it did, so let's go with parameter expansion.
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
dirname
is the command you're looking for, and assignments can't have spaces around the=
.
– Kusalananda♦
Aug 6 at 17:01
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f534190%2ffind-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
Assuming your files are sensibly named, i.e. no need for -print0
etc. You can do this with GNU find like this:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Output:
./Apple/Banana/Orange/Orange.md
./Apple/Banana/Papaya/Papaya.md
./Apple/Banana/Banana.md
If you only want the directory name, add a -printf
argument:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$' -printf '%hn'
Output when run on your updated test data:
GeneratedTest/A/AA
GeneratedTest/A
GeneratedTest/C/CC2
GeneratedTest/C/CC1
GeneratedTest/B
Even without GNU find:find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
3
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
1
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't requireprint0
.
– Jim L.
Aug 6 at 20:08
@Thor%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is%h
being used here?
– Nikhil
Aug 8 at 7:48
@Nikhil: Not withfind
, see section 3.2.2.1 in the manual for more details.
– Thor
Aug 8 at 10:22
add a comment |
Assuming your files are sensibly named, i.e. no need for -print0
etc. You can do this with GNU find like this:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Output:
./Apple/Banana/Orange/Orange.md
./Apple/Banana/Papaya/Papaya.md
./Apple/Banana/Banana.md
If you only want the directory name, add a -printf
argument:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$' -printf '%hn'
Output when run on your updated test data:
GeneratedTest/A/AA
GeneratedTest/A
GeneratedTest/C/CC2
GeneratedTest/C/CC1
GeneratedTest/B
Even without GNU find:find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
3
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
1
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't requireprint0
.
– Jim L.
Aug 6 at 20:08
@Thor%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is%h
being used here?
– Nikhil
Aug 8 at 7:48
@Nikhil: Not withfind
, see section 3.2.2.1 in the manual for more details.
– Thor
Aug 8 at 10:22
add a comment |
Assuming your files are sensibly named, i.e. no need for -print0
etc. You can do this with GNU find like this:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Output:
./Apple/Banana/Orange/Orange.md
./Apple/Banana/Papaya/Papaya.md
./Apple/Banana/Banana.md
If you only want the directory name, add a -printf
argument:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$' -printf '%hn'
Output when run on your updated test data:
GeneratedTest/A/AA
GeneratedTest/A
GeneratedTest/C/CC2
GeneratedTest/C/CC1
GeneratedTest/B
Assuming your files are sensibly named, i.e. no need for -print0
etc. You can do this with GNU find like this:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$'
Output:
./Apple/Banana/Orange/Orange.md
./Apple/Banana/Papaya/Papaya.md
./Apple/Banana/Banana.md
If you only want the directory name, add a -printf
argument:
find . -type f -regextype egrep -regex '.*/([^/]+)/1.md$' -printf '%hn'
Output when run on your updated test data:
GeneratedTest/A/AA
GeneratedTest/A
GeneratedTest/C/CC2
GeneratedTest/C/CC1
GeneratedTest/B
edited Aug 8 at 7:24
answered Aug 6 at 17:46
ThorThor
12.8k1 gold badge40 silver badges64 bronze badges
12.8k1 gold badge40 silver badges64 bronze badges
Even without GNU find:find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
3
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
1
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't requireprint0
.
– Jim L.
Aug 6 at 20:08
@Thor%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is%h
being used here?
– Nikhil
Aug 8 at 7:48
@Nikhil: Not withfind
, see section 3.2.2.1 in the manual for more details.
– Thor
Aug 8 at 10:22
add a comment |
Even without GNU find:find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
3
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
1
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't requireprint0
.
– Jim L.
Aug 6 at 20:08
@Thor%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is%h
being used here?
– Nikhil
Aug 8 at 7:48
@Nikhil: Not withfind
, see section 3.2.2.1 in the manual for more details.
– Thor
Aug 8 at 10:22
Even without GNU find:
find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
Even without GNU find:
find . -type f | egrep '.*/([^/]+)/1.md$'
– Jim L.
Aug 6 at 19:02
3
3
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
@JimL. Except that piping it to a line-oriented tool would break on some characters in filenames, like newline.
– Kusalananda♦
Aug 6 at 20:01
1
1
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't require
print0
.– Jim L.
Aug 6 at 20:08
@Kusalananda Agreed, however, this particular answer is predicated on "sensibly named" files that don't require
print0
.– Jim L.
Aug 6 at 20:08
@Thor
%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is %h
being used here?– Nikhil
Aug 8 at 7:48
@Thor
%h
in printf is used for int type of data to be formatted. Reference: printf format string - Wikipedia. Could you please explain that part? How is %h
being used here?– Nikhil
Aug 8 at 7:48
@Nikhil: Not with
find
, see section 3.2.2.1 in the manual for more details.– Thor
Aug 8 at 10:22
@Nikhil: Not with
find
, see section 3.2.2.1 in the manual for more details.– Thor
Aug 8 at 10:22
add a comment |
On a GNU system, you could do something like:
find . -name '*.md' -print0 |
gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
3
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Stéphane, I agree with steeldriver. Do mention the previouszsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.
– Kusalananda♦
Aug 6 at 18:38
1
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
add a comment |
On a GNU system, you could do something like:
find . -name '*.md' -print0 |
gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
3
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Stéphane, I agree with steeldriver. Do mention the previouszsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.
– Kusalananda♦
Aug 6 at 18:38
1
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
add a comment |
On a GNU system, you could do something like:
find . -name '*.md' -print0 |
gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
On a GNU system, you could do something like:
find . -name '*.md' -print0 |
gawk -v RS='' -F/ -v OFS=/ '
filename = $NF; NF--
if ($(NF)".md" == filename) include[$0]
else exclude[$0]
END for (i in include) if (!(i in exclude)) print i'
edited Aug 6 at 17:13
answered Aug 6 at 17:01
Stéphane ChazelasStéphane Chazelas
330k58 gold badges642 silver badges1009 bronze badges
330k58 gold badges642 silver badges1009 bronze badges
3
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Stéphane, I agree with steeldriver. Do mention the previouszsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.
– Kusalananda♦
Aug 6 at 18:38
1
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
add a comment |
3
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Stéphane, I agree with steeldriver. Do mention the previouszsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.
– Kusalananda♦
Aug 6 at 18:38
1
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
3
3
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
would you mind re-including your proposed zsh solution as an alternate? it would be helpful for those of us trying to learn more about zsh
– steeldriver
Aug 6 at 17:23
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Given that this answer has received more votes: To those who are upvoting this answer, could you please specify why this is better than the rest? It would help me to choose the most suitable answer.
– Nikhil
Aug 6 at 18:33
Stéphane, I agree with steeldriver. Do mention the previous
zsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.– Kusalananda♦
Aug 6 at 18:38
Stéphane, I agree with steeldriver. Do mention the previous
zsh
solution (it got, I believe, two of the upvotes), and feel free to point out any flaws in it that might have prompted you to remove it.– Kusalananda♦
Aug 6 at 18:38
1
1
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@steeldriver, in that zsh approach I (like you) had missed the part of the requirement that dirs that contain other md files should be omitted.
– Stéphane Chazelas
Aug 6 at 20:32
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
@StéphaneChazelas OP just clarified in the comments he actually meant for those to be included, it was just poorly phrased and people took it too literally.
– Kevin
Aug 7 at 20:59
add a comment |
find . -type d -exec sh -c '
dirpath=$1
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]' sh ; -print
The above would find all directories below the current directory (including the current directory) and would execute a short shell script for each.
The shell code would test whether there's a markdown file with the same name as the directory inside the directory, and whether this is the only *.md
name in that directory. If such a file exists and if it's the only *.md
name, the inline shell script exits with a zero exit status. Otherwise it exits with a non-zero exit status (signalling failure).
The set -- "$dirpath"/*.md
bit will set the positional parameters to the list of pathnames matching the pattern (matches any name with a suffix .md
in the directory). We can then use $#
later to see how many matches we got from this.
If the shell script exits successfully, -print
will print the path to the found directory.
Slightly speedier version that uses fewer invocations of the inline script, but that doesn't let you do more with the found pathnames in find
itself (the inline script may be further expanded though):
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] &&
[ "$#" -eq 1 ] &&
printf "%sn" "$dirpath"
done' sh +
The same commands but without caring about whether there are other .md
files in the directories:
find . -type d -exec sh -c '
dirpath=$1
[ -f "$dirpath/$dirpath##*/.md" ]' sh ; -print
find . -type d -exec sh -c '
for dirpath do
[ -f "$dirpath/$dirpath##*/.md" ] &&
printf "%sn" "$dirpath"
done' sh +
See also:
- Understanding the -exec option of `find`
add a comment |
find . -type d -exec sh -c '
dirpath=$1
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]' sh ; -print
The above would find all directories below the current directory (including the current directory) and would execute a short shell script for each.
The shell code would test whether there's a markdown file with the same name as the directory inside the directory, and whether this is the only *.md
name in that directory. If such a file exists and if it's the only *.md
name, the inline shell script exits with a zero exit status. Otherwise it exits with a non-zero exit status (signalling failure).
The set -- "$dirpath"/*.md
bit will set the positional parameters to the list of pathnames matching the pattern (matches any name with a suffix .md
in the directory). We can then use $#
later to see how many matches we got from this.
If the shell script exits successfully, -print
will print the path to the found directory.
Slightly speedier version that uses fewer invocations of the inline script, but that doesn't let you do more with the found pathnames in find
itself (the inline script may be further expanded though):
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] &&
[ "$#" -eq 1 ] &&
printf "%sn" "$dirpath"
done' sh +
The same commands but without caring about whether there are other .md
files in the directories:
find . -type d -exec sh -c '
dirpath=$1
[ -f "$dirpath/$dirpath##*/.md" ]' sh ; -print
find . -type d -exec sh -c '
for dirpath do
[ -f "$dirpath/$dirpath##*/.md" ] &&
printf "%sn" "$dirpath"
done' sh +
See also:
- Understanding the -exec option of `find`
add a comment |
find . -type d -exec sh -c '
dirpath=$1
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]' sh ; -print
The above would find all directories below the current directory (including the current directory) and would execute a short shell script for each.
The shell code would test whether there's a markdown file with the same name as the directory inside the directory, and whether this is the only *.md
name in that directory. If such a file exists and if it's the only *.md
name, the inline shell script exits with a zero exit status. Otherwise it exits with a non-zero exit status (signalling failure).
The set -- "$dirpath"/*.md
bit will set the positional parameters to the list of pathnames matching the pattern (matches any name with a suffix .md
in the directory). We can then use $#
later to see how many matches we got from this.
If the shell script exits successfully, -print
will print the path to the found directory.
Slightly speedier version that uses fewer invocations of the inline script, but that doesn't let you do more with the found pathnames in find
itself (the inline script may be further expanded though):
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] &&
[ "$#" -eq 1 ] &&
printf "%sn" "$dirpath"
done' sh +
The same commands but without caring about whether there are other .md
files in the directories:
find . -type d -exec sh -c '
dirpath=$1
[ -f "$dirpath/$dirpath##*/.md" ]' sh ; -print
find . -type d -exec sh -c '
for dirpath do
[ -f "$dirpath/$dirpath##*/.md" ] &&
printf "%sn" "$dirpath"
done' sh +
See also:
- Understanding the -exec option of `find`
find . -type d -exec sh -c '
dirpath=$1
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] && [ "$#" -eq 1 ]' sh ; -print
The above would find all directories below the current directory (including the current directory) and would execute a short shell script for each.
The shell code would test whether there's a markdown file with the same name as the directory inside the directory, and whether this is the only *.md
name in that directory. If such a file exists and if it's the only *.md
name, the inline shell script exits with a zero exit status. Otherwise it exits with a non-zero exit status (signalling failure).
The set -- "$dirpath"/*.md
bit will set the positional parameters to the list of pathnames matching the pattern (matches any name with a suffix .md
in the directory). We can then use $#
later to see how many matches we got from this.
If the shell script exits successfully, -print
will print the path to the found directory.
Slightly speedier version that uses fewer invocations of the inline script, but that doesn't let you do more with the found pathnames in find
itself (the inline script may be further expanded though):
find . -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*.md
[ -f "$dirpath/$dirpath##*/.md" ] &&
[ "$#" -eq 1 ] &&
printf "%sn" "$dirpath"
done' sh +
The same commands but without caring about whether there are other .md
files in the directories:
find . -type d -exec sh -c '
dirpath=$1
[ -f "$dirpath/$dirpath##*/.md" ]' sh ; -print
find . -type d -exec sh -c '
for dirpath do
[ -f "$dirpath/$dirpath##*/.md" ] &&
printf "%sn" "$dirpath"
done' sh +
See also:
- Understanding the -exec option of `find`
edited Aug 7 at 21:06
answered Aug 6 at 16:51
Kusalananda♦Kusalananda
160k18 gold badges316 silver badges502 bronze badges
160k18 gold badges316 silver badges502 bronze badges
add a comment |
add a comment |
Either
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
or
find . -type d -exec sh -c '
for d do
[ -f "$d/$d##*/.md" ] && printf "%sn" "$d"
done' find-sh +
To avoid running one sh
per file.
The find-sh
is an arbitrary string that becomes the shell's zeroth positional parameter $0
- making it something memorable may help with debugging in case the shell encounters errors (others may suggest using plain sh
or even _
as a default "skip" parameter).
add a comment |
Either
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
or
find . -type d -exec sh -c '
for d do
[ -f "$d/$d##*/.md" ] && printf "%sn" "$d"
done' find-sh +
To avoid running one sh
per file.
The find-sh
is an arbitrary string that becomes the shell's zeroth positional parameter $0
- making it something memorable may help with debugging in case the shell encounters errors (others may suggest using plain sh
or even _
as a default "skip" parameter).
add a comment |
Either
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
or
find . -type d -exec sh -c '
for d do
[ -f "$d/$d##*/.md" ] && printf "%sn" "$d"
done' find-sh +
To avoid running one sh
per file.
The find-sh
is an arbitrary string that becomes the shell's zeroth positional parameter $0
- making it something memorable may help with debugging in case the shell encounters errors (others may suggest using plain sh
or even _
as a default "skip" parameter).
Either
find . -type d -exec sh -c '[ -f "$1/$1##*/.md" ]' find-sh ; -print
or
find . -type d -exec sh -c '
for d do
[ -f "$d/$d##*/.md" ] && printf "%sn" "$d"
done' find-sh +
To avoid running one sh
per file.
The find-sh
is an arbitrary string that becomes the shell's zeroth positional parameter $0
- making it something memorable may help with debugging in case the shell encounters errors (others may suggest using plain sh
or even _
as a default "skip" parameter).
edited Aug 6 at 17:20
answered Aug 6 at 16:51
steeldriversteeldriver
42.2k5 gold badges56 silver badges94 bronze badges
42.2k5 gold badges56 silver badges94 bronze badges
add a comment |
add a comment |
Here's mine. I added some more directories and files to verify. I was also bored, so I added the last modified time and MD5. Maybe you're looking for duplicates.
GREEN='33[0;32m'
RED='33[0;31m'
NC='33[0m'
mkdir -pv Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin
touch Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin/Strawberry,Grape,Raisin.md
for dir in $(find ./ -type d)
do
dirname="$dir##*/"
fname="$dirname.md"
if [ -f "$dir/$fname" ]
then
STAT=$(stat --printf="%y %s" "$dir/$fname")
STAT="$STAT:0:19"
MD5=$(md5sum "$dir/$fname")
MD5="$MD5:0:32"
printf "$GREEN%-60s$NC%-40s%-40sn" "'$dir/$fname' exists" "$STAT" "$MD5"
else
echo -e "$RED'$dir/$fname' doesn't exist$NC"
fi
done
'.//.md' doesn't exist
'./Raisin/Raisin.md' doesn't exist
'./Raisin/Raisin/Raisin.md' exists 2019-08-07 19:54:09 a3085274bf23c52c58dd063faba0c36a
'./Raisin/Nababa/Nababa.md' doesn't exist
'./Raisin/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 3d2eca1d4a3c539527cb956affa8b807
'./Raisin/Grape/Grape.md' exists 2019-08-07 19:54:09 f577b20f93a51286423c1d8973973f01
'./Raisin/DragonFruit/DragonFruit.md' doesn't exist
'./Pear/Pear.md' doesn't exist
'./Pear/Raisin/Raisin.md' exists 2019-08-07 19:54:09 61387f5d87f125923c2962b389b0dd67
'./Pear/Nababa/Nababa.md' doesn't exist
'./Pear/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 02c9e39ba5b77954082a61236f786d34
'./Pear/Grape/Grape.md' exists 2019-08-07 19:54:09 43e85d5651cac069bba8ba36e754079d
'./Pear/DragonFruit/DragonFruit.md' doesn't exist
'./Apple/Apple.md' doesn't exist
'./Apple/Banana/Banana.md' exists 2019-08-07 19:54:09 a605268f3314411ec360d7e0dd234960
'./Apple/Banana/Papaya/Papaya.md' exists 2019-08-07 19:54:09 e759a879942fe986397e52b7ba21a9ff
'./Apple/Banana/Orange/Orange.md' exists 2019-08-07 19:54:09 127618fe9ab73937836b809fa0593572
'./Plaintain/Plaintain.md' doesn't exist
'./Plaintain/Raisin/Raisin.md' exists 2019-08-07 19:54:09 13ed6460f658ca9f7d222ad3d07212a2
'./Plaintain/Nababa/Nababa.md' doesn't exist
'./Plaintain/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 721d7a5a32f3eacf4b199b74d78b91f0
'./Plaintain/Grape/Grape.md' exists 2019-08-07 19:54:09 0bdaff592bbd9e2ed5fac5a992bb3566
'./Plaintain/DragonFruit/DragonFruit.md' doesn't exist
'./Grape/Grape.md' doesn't exist
'./Grape/Raisin/Raisin.md' exists 2019-08-07 19:54:09 aa5d4c970e7b4b6dc35cd16d1863b5bb
'./Grape/Nababa/Nababa.md' doesn't exist
'./Grape/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 8b02f8273bbff1bb3162cb088813e0c9
'./Grape/Grape/Grape.md' exists 2019-08-07 19:54:09 5593d7d6fdcbb48ab5901ba30469bbe8
add a comment |
Here's mine. I added some more directories and files to verify. I was also bored, so I added the last modified time and MD5. Maybe you're looking for duplicates.
GREEN='33[0;32m'
RED='33[0;31m'
NC='33[0m'
mkdir -pv Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin
touch Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin/Strawberry,Grape,Raisin.md
for dir in $(find ./ -type d)
do
dirname="$dir##*/"
fname="$dirname.md"
if [ -f "$dir/$fname" ]
then
STAT=$(stat --printf="%y %s" "$dir/$fname")
STAT="$STAT:0:19"
MD5=$(md5sum "$dir/$fname")
MD5="$MD5:0:32"
printf "$GREEN%-60s$NC%-40s%-40sn" "'$dir/$fname' exists" "$STAT" "$MD5"
else
echo -e "$RED'$dir/$fname' doesn't exist$NC"
fi
done
'.//.md' doesn't exist
'./Raisin/Raisin.md' doesn't exist
'./Raisin/Raisin/Raisin.md' exists 2019-08-07 19:54:09 a3085274bf23c52c58dd063faba0c36a
'./Raisin/Nababa/Nababa.md' doesn't exist
'./Raisin/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 3d2eca1d4a3c539527cb956affa8b807
'./Raisin/Grape/Grape.md' exists 2019-08-07 19:54:09 f577b20f93a51286423c1d8973973f01
'./Raisin/DragonFruit/DragonFruit.md' doesn't exist
'./Pear/Pear.md' doesn't exist
'./Pear/Raisin/Raisin.md' exists 2019-08-07 19:54:09 61387f5d87f125923c2962b389b0dd67
'./Pear/Nababa/Nababa.md' doesn't exist
'./Pear/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 02c9e39ba5b77954082a61236f786d34
'./Pear/Grape/Grape.md' exists 2019-08-07 19:54:09 43e85d5651cac069bba8ba36e754079d
'./Pear/DragonFruit/DragonFruit.md' doesn't exist
'./Apple/Apple.md' doesn't exist
'./Apple/Banana/Banana.md' exists 2019-08-07 19:54:09 a605268f3314411ec360d7e0dd234960
'./Apple/Banana/Papaya/Papaya.md' exists 2019-08-07 19:54:09 e759a879942fe986397e52b7ba21a9ff
'./Apple/Banana/Orange/Orange.md' exists 2019-08-07 19:54:09 127618fe9ab73937836b809fa0593572
'./Plaintain/Plaintain.md' doesn't exist
'./Plaintain/Raisin/Raisin.md' exists 2019-08-07 19:54:09 13ed6460f658ca9f7d222ad3d07212a2
'./Plaintain/Nababa/Nababa.md' doesn't exist
'./Plaintain/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 721d7a5a32f3eacf4b199b74d78b91f0
'./Plaintain/Grape/Grape.md' exists 2019-08-07 19:54:09 0bdaff592bbd9e2ed5fac5a992bb3566
'./Plaintain/DragonFruit/DragonFruit.md' doesn't exist
'./Grape/Grape.md' doesn't exist
'./Grape/Raisin/Raisin.md' exists 2019-08-07 19:54:09 aa5d4c970e7b4b6dc35cd16d1863b5bb
'./Grape/Nababa/Nababa.md' doesn't exist
'./Grape/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 8b02f8273bbff1bb3162cb088813e0c9
'./Grape/Grape/Grape.md' exists 2019-08-07 19:54:09 5593d7d6fdcbb48ab5901ba30469bbe8
add a comment |
Here's mine. I added some more directories and files to verify. I was also bored, so I added the last modified time and MD5. Maybe you're looking for duplicates.
GREEN='33[0;32m'
RED='33[0;31m'
NC='33[0m'
mkdir -pv Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin
touch Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin/Strawberry,Grape,Raisin.md
for dir in $(find ./ -type d)
do
dirname="$dir##*/"
fname="$dirname.md"
if [ -f "$dir/$fname" ]
then
STAT=$(stat --printf="%y %s" "$dir/$fname")
STAT="$STAT:0:19"
MD5=$(md5sum "$dir/$fname")
MD5="$MD5:0:32"
printf "$GREEN%-60s$NC%-40s%-40sn" "'$dir/$fname' exists" "$STAT" "$MD5"
else
echo -e "$RED'$dir/$fname' doesn't exist$NC"
fi
done
'.//.md' doesn't exist
'./Raisin/Raisin.md' doesn't exist
'./Raisin/Raisin/Raisin.md' exists 2019-08-07 19:54:09 a3085274bf23c52c58dd063faba0c36a
'./Raisin/Nababa/Nababa.md' doesn't exist
'./Raisin/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 3d2eca1d4a3c539527cb956affa8b807
'./Raisin/Grape/Grape.md' exists 2019-08-07 19:54:09 f577b20f93a51286423c1d8973973f01
'./Raisin/DragonFruit/DragonFruit.md' doesn't exist
'./Pear/Pear.md' doesn't exist
'./Pear/Raisin/Raisin.md' exists 2019-08-07 19:54:09 61387f5d87f125923c2962b389b0dd67
'./Pear/Nababa/Nababa.md' doesn't exist
'./Pear/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 02c9e39ba5b77954082a61236f786d34
'./Pear/Grape/Grape.md' exists 2019-08-07 19:54:09 43e85d5651cac069bba8ba36e754079d
'./Pear/DragonFruit/DragonFruit.md' doesn't exist
'./Apple/Apple.md' doesn't exist
'./Apple/Banana/Banana.md' exists 2019-08-07 19:54:09 a605268f3314411ec360d7e0dd234960
'./Apple/Banana/Papaya/Papaya.md' exists 2019-08-07 19:54:09 e759a879942fe986397e52b7ba21a9ff
'./Apple/Banana/Orange/Orange.md' exists 2019-08-07 19:54:09 127618fe9ab73937836b809fa0593572
'./Plaintain/Plaintain.md' doesn't exist
'./Plaintain/Raisin/Raisin.md' exists 2019-08-07 19:54:09 13ed6460f658ca9f7d222ad3d07212a2
'./Plaintain/Nababa/Nababa.md' doesn't exist
'./Plaintain/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 721d7a5a32f3eacf4b199b74d78b91f0
'./Plaintain/Grape/Grape.md' exists 2019-08-07 19:54:09 0bdaff592bbd9e2ed5fac5a992bb3566
'./Plaintain/DragonFruit/DragonFruit.md' doesn't exist
'./Grape/Grape.md' doesn't exist
'./Grape/Raisin/Raisin.md' exists 2019-08-07 19:54:09 aa5d4c970e7b4b6dc35cd16d1863b5bb
'./Grape/Nababa/Nababa.md' doesn't exist
'./Grape/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 8b02f8273bbff1bb3162cb088813e0c9
'./Grape/Grape/Grape.md' exists 2019-08-07 19:54:09 5593d7d6fdcbb48ab5901ba30469bbe8
Here's mine. I added some more directories and files to verify. I was also bored, so I added the last modified time and MD5. Maybe you're looking for duplicates.
GREEN='33[0;32m'
RED='33[0;31m'
NC='33[0m'
mkdir -pv Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin
touch Pear,Grape,Raisin,Plaintain/DragonFruit,Nababa,Strawberry,Grape,Raisin/Strawberry,Grape,Raisin.md
for dir in $(find ./ -type d)
do
dirname="$dir##*/"
fname="$dirname.md"
if [ -f "$dir/$fname" ]
then
STAT=$(stat --printf="%y %s" "$dir/$fname")
STAT="$STAT:0:19"
MD5=$(md5sum "$dir/$fname")
MD5="$MD5:0:32"
printf "$GREEN%-60s$NC%-40s%-40sn" "'$dir/$fname' exists" "$STAT" "$MD5"
else
echo -e "$RED'$dir/$fname' doesn't exist$NC"
fi
done
'.//.md' doesn't exist
'./Raisin/Raisin.md' doesn't exist
'./Raisin/Raisin/Raisin.md' exists 2019-08-07 19:54:09 a3085274bf23c52c58dd063faba0c36a
'./Raisin/Nababa/Nababa.md' doesn't exist
'./Raisin/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 3d2eca1d4a3c539527cb956affa8b807
'./Raisin/Grape/Grape.md' exists 2019-08-07 19:54:09 f577b20f93a51286423c1d8973973f01
'./Raisin/DragonFruit/DragonFruit.md' doesn't exist
'./Pear/Pear.md' doesn't exist
'./Pear/Raisin/Raisin.md' exists 2019-08-07 19:54:09 61387f5d87f125923c2962b389b0dd67
'./Pear/Nababa/Nababa.md' doesn't exist
'./Pear/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 02c9e39ba5b77954082a61236f786d34
'./Pear/Grape/Grape.md' exists 2019-08-07 19:54:09 43e85d5651cac069bba8ba36e754079d
'./Pear/DragonFruit/DragonFruit.md' doesn't exist
'./Apple/Apple.md' doesn't exist
'./Apple/Banana/Banana.md' exists 2019-08-07 19:54:09 a605268f3314411ec360d7e0dd234960
'./Apple/Banana/Papaya/Papaya.md' exists 2019-08-07 19:54:09 e759a879942fe986397e52b7ba21a9ff
'./Apple/Banana/Orange/Orange.md' exists 2019-08-07 19:54:09 127618fe9ab73937836b809fa0593572
'./Plaintain/Plaintain.md' doesn't exist
'./Plaintain/Raisin/Raisin.md' exists 2019-08-07 19:54:09 13ed6460f658ca9f7d222ad3d07212a2
'./Plaintain/Nababa/Nababa.md' doesn't exist
'./Plaintain/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 721d7a5a32f3eacf4b199b74d78b91f0
'./Plaintain/Grape/Grape.md' exists 2019-08-07 19:54:09 0bdaff592bbd9e2ed5fac5a992bb3566
'./Plaintain/DragonFruit/DragonFruit.md' doesn't exist
'./Grape/Grape.md' doesn't exist
'./Grape/Raisin/Raisin.md' exists 2019-08-07 19:54:09 aa5d4c970e7b4b6dc35cd16d1863b5bb
'./Grape/Nababa/Nababa.md' doesn't exist
'./Grape/Strawberry/Strawberry.md' exists 2019-08-07 19:54:09 8b02f8273bbff1bb3162cb088813e0c9
'./Grape/Grape/Grape.md' exists 2019-08-07 19:54:09 5593d7d6fdcbb48ab5901ba30469bbe8
answered Aug 8 at 0:01
user208145user208145
1,4312 gold badges14 silver badges17 bronze badges
1,4312 gold badges14 silver badges17 bronze badges
add a comment |
add a comment |
This would require a bit of logic.
for fd in `find . -type d`; do
dir=$fd##*/
if [ -f $fd/$dir.md ]; then
ls $fd/$dir.md
fi
done
You can also adapt that to fit into a one liner by using code blocks.
EDIT: Bash is hard. basedir
is not a command, dirname
doesn't do what I thought it did, so let's go with parameter expansion.
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
dirname
is the command you're looking for, and assignments can't have spaces around the=
.
– Kusalananda♦
Aug 6 at 17:01
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
add a comment |
This would require a bit of logic.
for fd in `find . -type d`; do
dir=$fd##*/
if [ -f $fd/$dir.md ]; then
ls $fd/$dir.md
fi
done
You can also adapt that to fit into a one liner by using code blocks.
EDIT: Bash is hard. basedir
is not a command, dirname
doesn't do what I thought it did, so let's go with parameter expansion.
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
dirname
is the command you're looking for, and assignments can't have spaces around the=
.
– Kusalananda♦
Aug 6 at 17:01
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
add a comment |
This would require a bit of logic.
for fd in `find . -type d`; do
dir=$fd##*/
if [ -f $fd/$dir.md ]; then
ls $fd/$dir.md
fi
done
You can also adapt that to fit into a one liner by using code blocks.
EDIT: Bash is hard. basedir
is not a command, dirname
doesn't do what I thought it did, so let's go with parameter expansion.
This would require a bit of logic.
for fd in `find . -type d`; do
dir=$fd##*/
if [ -f $fd/$dir.md ]; then
ls $fd/$dir.md
fi
done
You can also adapt that to fit into a one liner by using code blocks.
EDIT: Bash is hard. basedir
is not a command, dirname
doesn't do what I thought it did, so let's go with parameter expansion.
edited Aug 6 at 17:07
answered Aug 6 at 16:50
Zach SanchezZach Sanchez
1095 bronze badges
1095 bronze badges
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
dirname
is the command you're looking for, and assignments can't have spaces around the=
.
– Kusalananda♦
Aug 6 at 17:01
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
add a comment |
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
dirname
is the command you're looking for, and assignments can't have spaces around the=
.
– Kusalananda♦
Aug 6 at 17:01
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
That would be because I apparently can't remember bash commands or how they work.
– Zach Sanchez
Aug 6 at 17:00
dirname
is the command you're looking for, and assignments can't have spaces around the =
.– Kusalananda♦
Aug 6 at 17:01
dirname
is the command you're looking for, and assignments can't have spaces around the =
.– Kusalananda♦
Aug 6 at 17:01
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
Found that out pretty quickly after it was pointed out, and the spaces were a typo.
– Zach Sanchez
Aug 6 at 17:08
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
This breaks on all kinds of file names, especially with spaces. Don't parse the output of ls or find. See the other answers here for sensible approaches.
– Gilles
Aug 7 at 8:39
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
Ah, damn, you right, I would've thought the for loop would enumerate by newline, not by arbitrary whitespace. I break that rule all the time cause I seldom encounter files or directories with spaces, my bad.
– Zach Sanchez
Aug 7 at 15:38
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f534190%2ffind-only-those-folders-that-contain-a-file-with-the-same-name-as-the-folder%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Regarding your final remarks. Note that some answers do different things from others. Mine and Stéphane's for example, interpreted your first "Note" as "if there are other markdown files in the directory whatsoever, don't return that directory" while the others don't (as far as I can see). Apart from that, only you can pick the answer that is most helpful to you. Answers here will continue to receive up and down votes after you have accepted an answer, depending on what other readers find most useful.
– Kusalananda♦
Aug 6 at 18:47
When you say "Folders that contain markdown file whose names are different should not be found," do you mean to exclude directories with both? E.g. if you have
foo/foo.md
andfoo/bar.md
shouldfoo
be included or excluded?– Kevin
Aug 7 at 20:36
@Kevin In the example that you gave, I had meant to include foo. But unfortunately many people interpreted in the other way and they justified that. So, I thought that I was not clear in communication. So, I accepted answer which did not included foo.
– Nikhil
Aug 7 at 20:56
If you use
-printf
with find, you can get whatever part of the match you want, see my edit– Thor
Aug 8 at 7:26