LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 02-26-2024, 10:57 AM   #1
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
List files by size (easy-ish) - pass list to a bash script (difficult)


I had a nice little script, sadly I deleted the notes I took and I cannot recreate it.

I want to loop through a folder of files, order by size - biggest first, then pass that to a bash script to process it.
Quote:
ls -lS | awk '{print $9}'
But some files have spaces and it only prints the first word of the filename :-(

Last edited by GPGAgent; 02-26-2024 at 10:59 AM.
 
Old 02-26-2024, 11:17 AM   #2
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,140
Blog Entries: 6

Rep: Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828
Example:
Code:
files=$(du ~ | sort -nr)

echo "$files" | less
 
Old 02-26-2024, 11:18 AM   #3
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,897

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
ls is known to produce unparsable output, which is difficult to use in scripts.
Code:
ls -lS | awk ' { print substr($0, 48) } '
 
Old 02-26-2024, 11:29 AM   #4
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,732

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Code:
ls -1S
Works…yes? (That’s the number one. 1)
I don’t have any file names with imbedded spaces, but I’d expect the entire file name to be returned.
See the -Q option to ls to perhaps help with the input to your script.
My preference would be to “undo” the spaces in the file names, but that’s just me.

Last edited by scasey; 02-26-2024 at 11:36 AM.
 
Old 02-26-2024, 11:32 AM   #5
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by pan64 View Post
ls is known to produce unparsable output, which is difficult to use in scripts.
Code:
ls -lS | awk ' { print substr($0, 48) } '
Almost, but I only want the file name
Quote:
$ ls -lS | awk ' { print substr($0, 48) } '

5 D01.iso
5 D01.txt
5 DVDdd.txt
3 00Started-dd.txt
3 This has spaces
 
Old 02-26-2024, 11:34 AM   #6
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by scasey View Post
Code:
ls -1Sr
Works…yes? (That’s the number one. 1)
That's just fine
Quote:
$ ls -1S
D01.iso
D01.txt
DVDdd.txt
00Started-dd.txt
'This has spaces'
I removed the r because I want biggest first, I thought I tried this and it didn't do what I wanted, becuase i left the l in for long listing - doh!!!

Now how do I process this list?

Last edited by GPGAgent; 02-26-2024 at 11:39 AM.
 
Old 02-26-2024, 11:35 AM   #7
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by teckk View Post
Example:
Code:
files=$(du ~ | sort -nr)

echo "$files" | less
Sorry teckk, not exactly what i wanted, I'm only looking at the current directory.
 
Old 02-26-2024, 11:38 AM   #8
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,897

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
Quote:
Originally Posted by GPGAgent View Post
Almost, but I only want the file name
You need to adjust that 48 in your awk script to fit your needs (50), but anyway, the solution posted by scasey is much better and more elegant.
Code:
ls -1S
    ^  number one
 
Old 02-26-2024, 11:56 AM   #9
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,727

Rep: Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919Reputation: 5919
By default awk will split on spaces which is why you only see the first word in the filename. Parsing the output of ls is never a good idea.

Code:
find /dir/ -type f -printf '%p\n' | sort -nr
 
Old 02-26-2024, 12:01 PM   #10
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by pan64 View Post
You need to adjust that 48 in your awk script to fit your needs (50), but anyway, the solution posted by scasey is much better and more elegant.
Code:
ls -1S
    ^  number one
Yep, 48 to 50 works a treat

Last edited by GPGAgent; 02-26-2024 at 12:29 PM.
 
Old 02-26-2024, 12:07 PM   #11
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,140
Blog Entries: 6

Rep: Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828
Quote:
Now how do I process this list?
Code:
files=($(ls -1S))

for i in "${files[@]}"; do
    echo "Doing something with "$i""
    sleep .2
done
 
1 members found this post helpful.
Old 02-26-2024, 12:30 PM   #12
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by teckk View Post
Code:
files=($(ls -1S))

for i in "${files[@]}"; do
    echo "Doing something with "$i""
    sleep .2
done
Of course, cheers
 
Old 02-26-2024, 12:56 PM   #13
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,804

Rep: Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203
$(ls -1S) splits on whitespace, can go wrong.
Better is a while-read loop, where each read ends on newline.
Code:
ls -S |
  while IFS= read -r fn
  do
    echo "do sth with $fn"
  done
Standard shell and bash (unlike ksh and zsh) run the loop in a sub shell.
The following (if supported) runs the loop in the main shell:
Code:
while IFS= read -r fn <&3
do
  echo "do sth with $fn"
done 3< <(ls -S)
It's robust enough in practice. (Still not perfect, because a file name may contain a newline character.)
 
1 members found this post helpful.
Old 02-26-2024, 01:10 PM   #14
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by MadeInGermany View Post
$(ls -1S) splits on whitespace, can go wrong.
Better is a while-read loop, where each read ends on newline.
Code:
ls -S |
  while IFS= read -r fn
  do
    echo "do sth with $fn"
  done
Standard shell and bash (unlike ksh and zsh) run the loop in a sub shell.
The following (if supported) runs the loop in the main shell:
Code:
while IFS= read -r fn <&3
do
  echo "do sth with $fn"
done 3< <(ls -S)
It's robust enough in practice. (Still not perfect, because a file name may contain a newline character.)
Cheers Perfect, all in my notes now
Quote:
$ ls -S | while IFS= read -r fn; do echo "do sth with $fn"; done
do sth with D01.iso
do sth with D01.txt
do sth with DVDdd.txt
do sth with 00Started-dd.txt
do sth with This has spaces
 
Old 02-26-2024, 01:33 PM   #15
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,804

Rep: Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203
Last method, a for loop where InputFieldSeparator is set to newline only:
Code:
  saveIFS=$IFS
  IFS="
"
  for fn in $(ls -S)
  do
    echo "do sth with $fn"
  done
  IFS=$saveIFS
The same method works for the array assignment
Code:
  saveIFS=$IFS
  IFS="
"
  files=($(ls -S))
  IFS=$saveIFS
  for fn in "${files[@]}"
  do
    echo "do sth with $fn"
  done

Last edited by MadeInGermany; 02-26-2024 at 01:34 PM.
 
2 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How difficult or easy is Centos as a desktop distro ? hifi100 Linux - Newbie 28 06-11-2019 09:58 PM
How to pass in echo of log file creation to pass in to script to attach the file krazykracker Programming 1 08-10-2018 12:21 PM
[SOLVED] Updating Python to a newer version - easy or too difficult? grumpyskeptic Linux - Software 7 05-01-2017 10:42 AM
how to pass MySQL user/pass securely in shell script? digity Linux - Newbie 5 01-07-2010 05:48 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 11:21 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration