Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
285 views
in Technique[技术] by (71.8m points)

linux - recursively rename largest txt file in each directory using find command, Test Case Code included

What I am trying to accomplish is renaming the largest file size .txt file in each directory to keep.txt

here is a block of code you can run to setup a test case:

mkdir -p './file test/1 first'
mkdir -p './file test/2 second yay'
echo 'other file' > './file test/1 first/1other file.nfo'
echo 'smallest file' > './file test/1 first/1smallest file.txt'
echo 'this is a medium sized file' > './file test/1 first/1medium file.txt'
echo 'this is the very largest file of all the files' > './file test/1 first/1keep largest file.txt'
echo 'other file in the folder thats even larger than everything' > './file test/2 second yay/2other file.nfo'
echo 'smallest file' > './file test/2 second yay/2smallest file.txt'
echo 'this is the very largest file of all the files' > './file test/2 second yay/2keep largest file.txt'
cd 'file test'

output should look like this:

tree -L 9
.
├── 1 first
│?? ├── 1keep largest file.txt
│?? ├── 1medium file.txt
│?? ├── 1other file.nfo
│?? └── 1smallest file.txt
└── 2 second yay
    ├── 2keep largest file.txt
    ├── 2other file.nfo
    └── 2smallest file.txt

This command that I have put together seems to return just the largest txt files, but it does it multiple times, which seems to be part of the problem:

find . -type f -execdir sh -c 'ls -S1 -d "$PWD/"* | grep txt | head -n 1' ;

This is what I had in mind for renaming but it does not do what I expected and I cannot figure out why:

find . -type f -execdir sh -c 'ls -S1 -d "$PWD/"* | grep txt | head -n 1 | mv "{}" keep.txt' ;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

At the moment, you are executing the execdir command for every file found.

Another approach would be to use find's printf flag and print the size of the files and the path/name only, sorting the output before printing just the move command for the largest file and piping the command to sh to execute.

find . -name "*.txt" -printf '%s,%f,%h
' | sort -n | awk -F, '{ fil=$2;dir=$3 } END { print "mv ""dir"/"fil"" ""dir"/folder.jpg"" }'

We pipe through to sort to have the largest file at the bottom of the output, we then pip through to awk to get the last record, constructing the actual mv command.

Once you have verified that the mv command is as expected, execute it by piping through to sh and so:

find . -name "*.txt" -printf '%s,%f,%h
' | sort -n | awk -F, '{ fil=$2;dir=$3 } END { print "mv ""dir"/"fil"" ""dir"/folder.jpg"" }' | sh

To perform the solution on each directory, run:

while read line;do find "$line" -name "*.txt" -printf '%s,%f,%h
' | sort -n | awk -F, '{ fil=$2;dir=$3 } END { print "mv ""dir"/"fil"" ""dir"/folder.jpg"" }' | sh;done <<< "$(find . -type d)"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...