0

This question already has an answer here:

Content of myfile:

123  
**1    
**  

Script that attempts to display each word:

for i in $(cat $myfile)  
do  
  echo "$i"  
done  

the result is when echo *, it lists the files in my current directory which I dnno why. So I tried to process the * before echo it.

Content of another script:

for i in $(cat $myfile)  
do  
  if [[ $i == *\+ ]](regex pattern find 1 * or more.)  
  then  
       (?what should I do. I tried i="\*",i="*" etc.; it doesn't work)  
  fi  
  echo "$i"  
done

marked as duplicate by muru, αғsнιη, cas, Archemar, Raphael Ahrens Jan 29 '18 at 16:36

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • thanks for editing!! i am new in linux .you mean using script to processing text is a bad practice? i expect the shell can do more. anyway do you have solution ?? i just want to know why. if i echo * in a script solely.its okay but if i loop every word in text file and pass to variable and echo it.something wrong with the asterisk character! – kelvin .C Jan 29 '18 at 5:43
  • The shell can do more, but other tools can do it better. It depends on what you want to do with the text. – muru Jan 29 '18 at 5:45
3

The file name globbing happens on the for-line, with the expansion of $(cat $myfile), not in the echo.

When looping over the contents of a file, use read:

while IFS= read -r words; do
    printf '%s\n' "$words"
done <"$myfile"

See also:


If you want to have each whitespace-separate word on its own line of output:

awk '{ for (i = 1; i <= NF; ++i) print $i }' "$myfile"
  • Actually, since the OP says they are trying to display each word in the file, changing IFS might not be the right thing to do. – G-Man Jan 29 '18 at 7:12
  • 1
    @G-Man If you want to read more words with read, then you have to use more variables. It's better to use awk (as I've done) or possibly (but not really) readarray/mapfile. – Kusalananda Jan 29 '18 at 7:37
3

The right answer is: Don’t use a shell loop to process text.  But, if you want a quick fix,

set -o noglob
for i in $(cat $myfile)
do
    echo "$i"
done
set +o noglob

The noglob option prevents pathname expansion, so you can say echo * and get a * rather than a list of files.

-1

You're really asking two questions, but both speak to how the shell treats the character *. That character has special meaning to the shell, and as you discovered, it acts as a particular form of regular expression known in the shell man pages as a glob for file names. That's why you got the list of file names in your current directory, It is supposed to that. Refer to the shell man page section on globbing for a detailed description of all the forms of that particular kind of regular expression syntax.

The second part of question seems to be asking how to avoid that from happening. There are two ways. Either escape the character by preceding it with a back slash \, or put it in single quotes, ie. '*'.

  • A filename globbing pattern is not a "special form of regular expression". – Kusalananda Jan 29 '18 at 6:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.