Question

I'm trying to use the ? wildcard to display only 1 character files, and ?.* to display 1 character files with extensions.

what works:

cd /mydir

ls ? ?.*

I'm trying to use this in a shell script so therefor i cant use "cd"

What i'm trying to get to work

ls ? ?.* /mydir

and it gives me the output:

ls: cannot access ?.*: No such file or directory

I've also tried:

ls /mydir ? ?.*

which gives me the exact same output as before.

Was it helpful?

Solution 2

When you write ls ? ?.* /mydir, you're trying to display the files matching three distincts patterns: ?, ?.*, and /mydir. You want to match only /mydir/? and /mydir/?.*, hence this command: ls /mydir/? /mydir/?.*.

Edit: while this is a correct answer to the initial question (listing /mydir/? and /mydir/?.*), OP wanted to do this to parse the output and get the file count. See @gniourf_gniourf's answer, which is a much better way to do this.

OTHER TIPS

From a comment you wrote:

im in college for linux administrator and 1 of my current classes in shell scripting. My teacher is just going over basic stuff. And, my current assingment is to get the number of files in the tmp directory of our class server, the number of files that end in .log and the number of files that only have 1 character names and store the data in a file and then display the stored data to the user. I know it's stupid, but it's my assignment.

I only hope that they don't teach you to parse the output of ls in college... it's one of the most terrible things to do. Please refer to these links:

The solution you chose

ls /mydir/? /mydir/?.* | wc -l

is broken in two cases:

  • If there are no matching files, you'll get an error. You can fix that in two ways: use shopt -s nullglob or just redirect stderr to devnull.
  • If there's a newline in a file name. Try it: touch $'a.lol\nlol\n\lol\nlol\nlol'. LOL.

The proper bash way is the following:

shopt -s nullglob
shopt -u failglob
files=( /mydir/? /mydir/?.* )
echo "There are ${#files[@]} files found."

cd works perfectly within a shell script, use it. For minimal impact on the script, I would use a subshell:

( cd /mydir && ls ? ?.* )

That way, you don't change the current working directory of the script (and neither $OLDPWD, which would be clobbered with cd /mydir; ...; cd -;).

While ls seems like an obvious choice, find is probably more suitable:

find /mydir \! -name "." -a \( -name "?" -o -name "?.*" \)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top