Question

In a folder I have many files with several parameters in filenames, e.g (just with one parameter) file_a1.0.txt, file_a1.2.txt etc.
These are generated by a c++ code and I'd need to take the last one (in time) generated. I don't know a priori what will be the value of this parameter when the code is terminated. After that I need to copy the 2nd line of this last file.

To copy the 2nd line of the any file, I know that this sed command works:

sed -n 2p filename

I know also how to find the last generated file:

ls -rtl file_a*.txt | tail -1

Question:

how to combine these two operation? Certainly it is possible to pipe the 2nd operation to that sed operation but I dont know how to include filename from pipe as input to that sed command.

Was it helpful?

Solution

You can use this,

ls -rt1 file_a*.txt | tail -1 | xargs sed -n '2p'

(OR)

sed -n '2p' `ls -rt1 file_a*.txt | tail -1`

sed -n '2p' $(ls -rt1 file_a*.txt | tail -1)

OTHER TIPS

Typically you can put a command in back ticks to put its output at a particular point in another command - so

sed -n 2p `ls -rt name*.txt | tail -1 `

Alternatively - and preferred, because it is easier to nest etc -

sed -n 2p $(ls -rt name*.txt | tail -1)

-r in ls is reverse order.

   -r, --reverse
          reverse order while sorting

But it is not good idea when used it with tail -1.

With below change (head -1 without r option in ls), performance will be better, that you needn't wait to list all files then pipe to tail command

sed -n 2p $(ls -t1 name*.txt | head -1 )

I was looking for a similar solution: taking the file names from a pipe of grep results to feed to sed. I've copied my answer here for the search & replace, but perhaps this example can help as it calls sed for each of the names found in the pipe:

this command to simply find all the files:

grep -i -l -r foo ./* 

this one to exclude this_shell.sh (in case you put the command in a script called this_shell.sh), tee the output to the console to see what happened, and then use sed on each file name found to replace the text foo with bar:

grep -i -l -r --exclude "this_shell.sh" foo ./* | tee  /dev/fd/2 | while read -r x; do sed -b -i 's/foo/bar/gi' "$x"; done 

I chose this method, as I didn't like having all the timestamps changed for files not modified. Feeding the grep result allows only the files with target text to be looked at (thus likely may improve performance / speed as well)

be sure to backup your files & test before using. May not work in some environments for files with embedded spaces. (?)

fwiw - I had some problems using the tail method, it seems that the entire dataset was generated before calling tail on just the last item.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top