Iterating over each line of ls -l output

LinuxShell

Linux Problem Overview


I want to iterate over each line in the output of: ls -l /some/dir/*

Right now I'm trying: for x in $(ls -l $1); do echo $x; done

However, this iterates over each element in the line separately, so I get:

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:07
File1

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:17
File2

But I want to iterate over each line as a whole, though. How do I do that?

Linux Solutions


Solution 1 - Linux

Set IFS to newline, like this:

IFS='
'
for x in `ls -l $1`; do echo $x; done

Put a sub-shell around it if you don't want to set IFS permanently:

(IFS='
'
for x in `ls -l $1`; do echo $x; done)

Or use while | read instead:

ls -l $1 | while read x; do echo $x; done

One more option, which runs the while/read at the same shell level:

while read x; do echo $x; done << EOF
$(ls -l $1)
EOF

Solution 2 - Linux

It depends what you want to do with each line. awk is a useful utility for this type of processing. Example:

 ls -l | awk '{print $9, $5}'

.. on my system prints the name and size of each item in the directory.

Solution 3 - Linux

As already mentioned, awk is the right tool for this. If you don't want to use awk, instead of parsing output of "ls -l" line by line, you could iterate over all files and do an "ls -l" for each individual file like this:

for x in * ; do echo `ls -ld $x` ; done

Solution 4 - Linux

You can also try the find command. If you only want files in the current directory:

> find . -d 1 -prune -ls

Run a command on each of them?

> find . -d 1 -prune -exec echo {} \;

Count lines, but only in files?

> find . -d 1 -prune -type f -exec wc -l {} \;

Solution 5 - Linux

The read(1) utility along with output redirection of the ls(1) command will do what you want.

Solution 6 - Linux

So, why didn't anybody suggest just using options that eliminate the parts he doesn't want to process.

On modern Debian you just get your file with:

ls --format=single-column 

Further more, you don't have to pay attention to what directory you are running it in if you use the full directory:

ls --format=single-column /root/dir/starting/point/to/target/dir/

This last command I am using the above and I get the following output:

bot@dev:~/downloaded/Daily# ls --format=single-column /home/bot/downloaded/Daily/*.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141119_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141120_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141121_IENT1.txt.gz

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIvanView Question on Stackoverflow
Solution 1 - LinuxRandy ProctorView Answer on Stackoverflow
Solution 2 - LinuxAdam HolmbergView Answer on Stackoverflow
Solution 3 - LinuxAxelView Answer on Stackoverflow
Solution 4 - LinuxDavid KoskiView Answer on Stackoverflow
Solution 5 - LinuxSteve EmmersonView Answer on Stackoverflow
Solution 6 - LinuxBradChesney79View Answer on Stackoverflow