Can we use the mv command to move by terminal line numbers?

I use this command “du -sh * | sort -n | nl” to get a nice organised list of files. The nl command shows each terminal output line with a number. Is there any way to then tell the mv command to move the files that are on say line 25-30? instead of needing to type the files name?

Have you tried filtering the returned lines with grep ?

mv ./"$(ls | awk 'NR==<line_number>')" <folder_path> #works only for 1 file at a time
1 Like
du -sh * | sort -n | nl | head -30 | tail -n +25 | cut -f 3

head gives you the first 30 lines and tail removes the first 25 out of them.

3 Likes

Thanks for reply. With this command it tells me it cant move because device is busy.

mv ./"$(ls | awk ‘NR==25-30’)" test/
mv: cannot move ‘./’ to ‘test/.’: Device or resource busy

du -sh * | sort -n | nl | head -30 | tail -n +25 | cut -f 3

This cuts the list and only shows those lines. Very good to know thanks. :+1: But unfortunatly I don’t know how to move them after that :man_shrugging:

It’s simple. Just put the output into two brackets after a dollar sign like this:

mv $(du -sh * | sort -n | nl | head -30 | tail -n +25 | cut -f 3) /path/you/want/to/move

I forgot about the mv part in your question, sorry

2 Likes

Thanks looks like this is about to work. Right now I’m getting stat error and saying files cannot be found. I’m really thinking this is because the files have spaces in the names. any way to get around this?

Yeah, whitespaces can be pretty troublesome not only in GNU/Linux. The only quick solution I can think of is to replace the whitespaces with underscores in your directory.

1 Like

That is awsome. It worked. :clap:

you could use for instead of $(…) with mv. And then quoting " "

for F in $(...) ; do echo "$F" ; done

Then replace echo with mv

2 Likes

for F in $(…) ; do echo “$F” ; done

I can confirm this is another good way. I think this would also work even if the files had spaces becasue of using the quotes. I’ll find that out in a bit.

To extend, it’s useful to create a bash script for this, so you don’t need to type the whole pipelined commands.

I haven’t tested it yet, but it should be something like below.

Name it something like lsnice:

#!/usr/bin/bash

du -sh * | sort -n | nl

Name it something like mvline:

#!/usr/bin/bash

# $1 is argument for "from" line number
# $2 is argument for "to" line number
# $3 is argument for destination directory

for F in $(du -sh * | sort -n | nl | head -$1 | tail -n +$2 | cut -f 3) ; do mv "$F" $3 ; done
2 Likes

Very interesting. I don’t know much when it comes scripting but how would $1, $2 and $3 get there values? Just by typing the value’s in proper order after the script name?

If you’d write a script just like @JiaZhang suggested, you can use for instance

mvline 30 25 "~/Documents"

where $1 will be replaced with 30, $2 with 25 and $3 with ~/Documents for you

1 Like

That would be perfect. But the script would then always have to be placed in the directory wouldn’t it?

Place it in /usr/local/bin and make sure it is executable.

1 Like

Of course, how did i miss that.

Big thanks to every one for your input. This will save me a lot of time .

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.