1

sorry for that odd title. I didn't know how to word it the right way.

I'm trying to write a script to filter my wiki files to those got directories with the same name and the ones without. I'll elaborate further.

here is my file system:

enter image description here

what I need to do is print a list of those files which have directories in their name and another one of those without.

So my ultimate goal is getting:

with dirs:

Docs
Eng
Python
RHEL
To_do_list
articals

without dirs:

orphan.txt
orphan2.txt
orphan3.txt

I managed to get those files with dirs. Here is me code:

getname () {
        file=$( basename "$1" )
        file2=${file%%.*}
        echo $file2
        }

for d in  Mywiki/* ; do

    if [[ -f $d ]]; then
        file=$(getname $d)

        for x in  Mywiki/* ; do
            dir=$(getname $x)

            if [[ -d $x ]] && [ $dir == $file ]; then
            echo $dir
            fi
        done

    fi

done

but stuck with getting those without. if this is the wrong way of doing this please clarify the right one.

any help appreciated. Thanks.

0xMH
  • 1,825
  • 20
  • 26

3 Answers3

1

That may not be the most efficient way of doing it, but you could take all files, remove the extension, and the check if there isn't a directory with that name.

Like this (untested code):

for file in  Mywiki/* ; do
    if [ -f "$d" ]; then
        dirname=$(getname "$d")
        if [ ! -d "Mywiki/$dirname" ]; then
           echo "$file"
        fi
    fi
done
Khoyo
  • 1,253
  • 11
  • 20
  • All the variable interpolations need to be in double quotes in order for this to be robust against file names with whitespace or shell metacharacters in them. – tripleee Aug 30 '17 at 06:10
1

Here's a quick attempt.

for file in Mywiki/*.txt; do
    nodir=${file##*/}
    test -d "${file%.txt}" && printf "%s\n" "$nodir" >&3 || printf "%s\n" "$nodir"
done >with 3>without

This shamelessly uses standard output for the non-orphans. Maybe more robustly open another separate file descriptor for that.

Also notice how everything needs to be quoted unless you specifically require the shell to do whitespace tokenization and wildcard expansion on the value of a token. Here's the scoop on that.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • can you explain this line a little please `test -d "${file%.txt}" && printf "%s\n" "$nodir" >&3 || printf "%s\n" "$nodir" ` – 0xMH Aug 31 '17 at 23:44
  • I got it finally. and converted it too cause I wanted to make other stuff than saving it. Thanks dude I really appreciate your help. – 0xMH Sep 01 '17 at 00:01
  • Just for the record, `a && b || c` is a boolean short-circuit which could more verbosely be written `if a; then b; else c; fi` – tripleee Sep 01 '17 at 03:44
-1

To List all the files in current dir

list1=`ls -p | grep -v /`

To List all the files in current dir without extension

list2=`ls -p | grep -v / | sed 's/\.[a-z]*//g'`

To List all the directories in current dir

list3=`ls -d */ | sed -e "s/\///g"`

Now you can get the desired directory listing using intersection of list2 and list3. Intersection of two lists in Bash

nagendra547
  • 5,672
  • 3
  • 29
  • 43
  • None of the code examples here work, let alone do what the prose says they do. – tripleee Aug 30 '17 at 06:08
  • `list1=ls -p` means assign the value `ls` to `list1` while attempting to execute `-p` which isn't a valid command. I guess you are probably looking for a command substitution `list1=($(ls -p | grep -v /))` but you should [avoid using `ls` in scripts](http://mywiki.wooledge.org/ParsingLs) – tripleee Aug 30 '17 at 06:19
  • Yes command substitution. Just updated my ans. Someway I guess, formatting caused you confusion. Basically store the output of command in list. – nagendra547 Aug 30 '17 at 06:22
  • That's still not robust against filenames with whitespace or shell metacharacters. Reading the output of `ls` into an array would nominally solve that, but really, that's why we have `printf "%q"`. So `all=($(printf " %q" *))` puts all the file names in one array, and `dirs=($(printf " %q" */))` puts all the directories in another. Now proceed to find out how to do [array intersection and difference](https://stackoverflow.com/questions/2312762/compare-difference-of-two-arrays-in-bash). – tripleee Aug 30 '17 at 07:05