1

I did this script

#!/bin/bash

liste=`ls -l`
for i in $liste
do
    echo $i
done

The problem is I want the script displays each result line by line, but it displays word by word :

I have :

my_name
etud 
4096
Oct
8
10:13

and I want to have :

my_name etud 4096 Oct 8 10:13

The final aim of the script is to analyze each line ; it is the reason I want to be able to recover the entire line. Maybe the list is not the best solution but I don't know how to recover the lines.

2

5 Answers 5

1

To start, we'll assume that none of your filenames ever contain newlines:

ls -l | IFS= while read -r line; do
    echo "$line"
    # Do whatever else you want with $line
done

If your filenames could contain newlines, things get tricky. In this case, it's better (although slower) to use stat to retrieve the desired metadata from each file individually. Consult man stat for details about how your local variety of stat works, as it is unfortunately not very standardized.

for f in *; do
    line=$(stat -c "%U %n %s %y" "$f")  # One possibility
    # Work with $line as if it came from ls -l
done
Sign up to request clarification or add additional context in comments.

1 Comment

True. If you have to run a new process for each file anyway, though, the control over the output that stat allows may be more convenient. (But yeah, I simply overlooked that you could call ls for each file.)
0

You can replace

echo $i

with

echo -n "$i "

echo -n outputs to console without newline.

4 Comments

echo -n is not POSIX standard. printf is the safe, portable approach.
@Charles Duffy, it is defined in IEEE Std 1003.1-2001 POSIX.
@JimBlack Only as an XSI extension.
@JimBlack quote: "The System V echo does not support any options, but allows escape sequences within its operands, as described for XSI implementations in the OPERANDS section." Another quote: "It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted."
0

Another to do it with a while loop and without a pipe:

#!/bin/bash

while read line
do
    echo "line: $line"
done < <(ls -l)

1 Comment

This is correct (except for using read without -r -- thus having escape sequences interpreted -- and leaving $IFS at defaults -- and thus having trailing whitespace stripped), if the goal is to demonstrate reading from a stream. It's incorrect, if the goal is to demonstrate reading a list of files (some people really do think that ls is the right way to do this!). It would be good for an answer to be more clear.
0

First, I hope that you aren't genuinely using ls in your real code, but only using it as an example. If you want a list of files, ls is the wrong tool; see http://mywiki.wooledge.org/ParsingLs for details.

Second, modern versions of bash have a builtin called readarray.

Try this:

readarray -t my_array < <(ls -l)
for entry in "${my_array[@]}"; do
  read -a pieces <<<"$entry"
  printf '<%s> ' "${pieces[@]}"; echo
done

First, it creates an array (called my_array) with all the output from the command being run.

Then, for each line in that output, it creates an array called pieces, and emits each piece with arrow brackets around them.

If you want to read a line at a time, rather than reading the entire file at once, see http://mywiki.wooledge.org/BashFAQ/001 ("How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?")

2 Comments

<(ls -l) will fail under the same circumstances as ls -l | while read....
@chepner If your meaning is ls-specific, I don't believe I ever implied anything to the contrary -- see the first paragraph of my answer. (That said, unless you don't consider losing any process-local state relating to the content you've read "failing", I can't agree with the accuracy of the objection in the general, non-ls-specific case)
0

Joinning the previous answers with the need to store the list of files in a variable. You can do this

echo -n "$list"|while read -r lin
do
 echo $lin
done

Comments

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.