Writing directory entries with grep

I am trying to list all entries in a directory whose names contain ONLY uppercase letters. Directories need to be added "/".

#!/bin/bash
cd ~/testfiles/
ls | grep -r *.*

      

Since grep by default only looks for lowercase letters (right?), I just recursively loop through the directories in the test files for all names that only contain uppercase letters.

Unfortunately this doesn't work.

As far as adding directories, I'm not sure why I need this. Does anyone know where I can start with a detailed explanation of what I can do with grep? Also, how to solve my problem?

+3


source to share


3 answers


No, grep doesn't just look at capital letters.

Your question I'm a little unclear, for example:

  • from your use of the -r parameter, it seems you want to search recursively, but you don't say so. For the sake of simplicity, I'm assuming you don't need; consider @twm answer if you need recursion.
  • you only want to search for uppercase (letters). Does this mean you don't want to accept any other (non-alphabetic) characters, but as long as they are not valid for filenames (like numbers or dashes, periods, etc.).
  • since you are not saying that i am not allowed to have only a file per line, i assume that is ok (using ls -1

    ).

A naive solution would be:

ls -1 | grep "^[[:upper:]]\+$"

      

That is, print all lines containing only uppercase letters. In my TEMP directory that prints like:

ALLBIG
LCFEM
WPDNSE

      

However, this would exclude files of type README.TXT

or FILE001

, which, depending on your requirements (see above), are likely to be included.

So the best solution would be this:



ls -1 | grep -v "[[:lower:]]\+"

      

That is, print all lines that do not contain a lowercase letter. In my TEMP directory that prints like:

ALLBIG
ALLBIG-01.TXT
ALLBIG005.TXT
CRX_75DAF8CB7768
LCFEM
WPDNSE
~DFA0214428CD719AF6.TMP

      

Finally, you can use the -F

(or --classify

) option to "properly label" directories with a "/" .

ls -1F | grep -v "[[:lower:]]\+"

      

Again, example output:

ALLBIG
ALLBIG-01.TXT
ALLBIG005.TXT
CRX_75DAF8CB7768
LCFEM/
WPDNSE/
~DFA0214428CD719AF6.TMP

      

Note that a different option will be used find

if you can live with a different output (e.g. find ! -regex ".*[a-z].*"

), but it will have a different output.

+1


source


The exact regexp depends on the output format of your ls command. Assuming you are not using an alias for ls, you can try this:

ls -R  | grep -o -w "[A-Z]*"

      



note that with -R

ls you will recursively list directories and files in the current directory. The grep option -o

tells grep to only print the corresponding portion of the text. The options -w

tell grep to match only whole words. "[A-Z]*"

is a regular expression to filter only words with upper cooling.

Note that this regex will print TEST.txt as well as TEXT.TXT. In other words, it will only consider names that are formed by letters.

0


source


It ls

's the one that lists the files, not grep

, so you need to specify that you want to add // to the directories. Use ls --classify

to add "/" to directories.

grep

is used to process results from ls

(or usually another source), and display only lines that match the specified pattern. It is not limited to uppercase letters. You can limit it to only uppercase characters and "/" with grep -E '^[A-Z/]*$

, or if you also want numbers, periods, etc. You may have been filtering out lines containing lowercase characters with grep -v -E [a-z]

.

Since grep

it is not a program that lists the files, this is not where you want to recurse. ls

can recursively list paths if you are using ls -R

. However, you are just going to get the last component of the file path this way.

You might want to use find

recursion for handling. This works for me:

find . -exec ls -d --classify {} \; | egrep -v '[a-z][^/]*/?$'

It should be noted that using ls --classify

"/" to append to the end of directories can also add some other characters to other types of paths that it can classify. For example, it can add "*" to the end of executable files. If you are not, but you are fine with listing directories and other paths separately, this could be worked around by doing it find

twice - once for directories and then again for other paths. This works for me:

find . -type d | egrep -v '[a-z][^/]*$' | sed -e 's#$#/#'

find . -not -type d | egrep -v '[a-z][^/]*$'

0


source







All Articles