010-160 · Question #22
A directory contains the following files: a.txt b.txt c.cav What would be the output of the following shell script? for file in * .txt do echo $file done
The correct answer is E. A. txt. In 'for file in .txt' the space causes and .txt to be separate tokens, so * expands to all files in the directory and .txt is echoed as a literal string.
Question
Options
- A*.txt
- Ba b
- Cc.cav
- Da.txt
- EA. txt
- Ftxt
How the community answered
(24 responses)- B8% (2)
- C8% (2)
- D4% (1)
- E79% (19)
Why each option
In 'for file in * .txt' the space causes * and .txt to be separate tokens, so * expands to all files in the directory and .txt is echoed as a literal string.
The glob * expands successfully to existing files, so it is never output as the unexpanded literal *.txt.
The loop echoes full filenames including extensions, not bare basenames like 'a' and 'b'.
c.cav is only one of several values echoed; the loop iterates over all files matched by * plus the literal .txt.
a.txt alone is insufficient because the loop also echoes b.txt, c.cav, and the literal .txt due to the space-separated tokens.
Because there is a space between * and .txt, the shell treats them as two separate words: * expands to all files in the directory (a.txt, b.txt, c.cav) and .txt is passed as a literal string. The loop therefore echoes a.txt, b.txt, c.cav, and .txt on separate lines, producing more output than any single-file answer reflects.
The literal token is .txt with its leading dot, not the bare string txt without a dot.
Concept tested: Shell glob expansion and word splitting in for loops
Source: https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching
Topics
Community Discussion
No community discussion yet for this question.