0

I need some help, guys. I have a bash code

#!/bin/bash
echo "Iveskite kataloga, kurio analize norite atlikti"
read katalogas
failai=$(find -x $katalogas)
for failas in $failai
do
  if [[ -d "$failas" ]]
  then 
    echo $failas " yra direktorija "
  else
    if [[ -x "$failas" ]]
    then
      echo $failas " yra vykdomasis failas "
    else
      if [[ -f "$failas" ]]
      then
        echo $failas " yra paprastasis failas "
      fi
    fi
  fi
done

I want to make, that the final result would be sorted by file type. I do this: failai=$(find -x $katalogas) but It seems not working.

6
  • What platform are you on? I have never seen the -x flag to find before so I'm not sure what it's supposed to do Commented May 9, 2015 at 15:45
  • Don't iterate the results of find like that! What do you think will happen if there's a file with whitespace in its name? Commented May 9, 2015 at 15:48
  • 1
    @Eric Renouf, from manage for BSD find "−x Prevent find from descending into directories that have a device number different than that of the file from which the descent began." Commented May 9, 2015 at 15:48
  • Also, you might be interested in the fact that bash supports elif so you can avoid else if nesting like you're doing Commented May 9, 2015 at 15:48
  • It's linux, if I understand your question correct (I test it on Yosemite terminal) Commented May 9, 2015 at 15:48

2 Answers 2

2

A solution that means you keep your script mostly unchanged:

#!/bin/bash
echo "Iveskite kataloga, kurio analize norite atlikti"
read katalogas
failai=$(find -x $katalogas)
typeD=fileslist1
typeX=filelist2
typeF=filelist3
> $typeD
> $typeX
> $typeF
for failas in $failai
do
  if [[ -d "$failas" ]]
  then 
    echo $failas " yra direktorija " >> $typeD
  else
    if [[ -x "$failas" ]]
    then
      echo $failas " yra vykdomasis failas " >> $typeX
    else
      if [[ -f "$failas" ]]
      then
        echo $failas " yra paprastasis failas " >> $typeF
      fi
    fi
  fi
done
cat $typeD $typeX $typeF

Or, to avoid writing to files and using "sort", you would need to add a sort key to your output accordingly, i.e. change the "D:" "X:" and "F:" to fix the order as required:

#!/bin/bash
echo "Iveskite kataloga, kurio analize norite atlikti"
read katalogas
failai=$(find -x $katalogas)

for failas in $failai
do
  if [[ -d "$failas" ]]
  then 
    echo "A: $failas  yra direktorija "
  else
    if [[ -x "$failas" ]]
    then
      echo "X: $failas yra vykdomasis failas "
    else
      if [[ -f "$failas" ]]
      then
        echo "F: $failas yra paprastasis failas "
      fi
    fi
  fi
done | sort

You can option add a " | cut -d':' -f2- " after the "sort" to remove the sort key.

Sign up to request clarification or add additional context in comments.

Comments

1

It's probably simplest to just run find three times. (This also avoids any issues that might come up while trying to store all the found file names in a single list, such as with file names containing spaces.) Unless katalogas contains a lot of files, this is unlikely to be a bottleneck for your script.

echo "Iveskite kataloga, kurio analize norite atlikti"
read katalogas
# First, get the directories
find -x "$katalogas" -type d
# Next, get anything with a permission bit set
# Ignore directories you already found
find -x "$katalogas" -not -type d -perm -111
# Find any regular files not matched by the above
find -x "$katalogas" -not -type d -not -perm -111 -type f 

4 Comments

find: -perm: x: illegal mode string
Oh, I missed the last line of the docs that say a symbolic mode may not begin with a dash. Try -perm -111 instead.
Hm. -perm isn't working the way I expect. I seem to be getting a lot of files that don't have any execute bits set.
use the -executable flag maybe? I think this solution is probably the best if you can get it working. The file cache will mean it doesn't have to actually do much actual disk reading after the first find.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.