I want to get the last two lines of the find output and copy them somewhere. I tried
find . -iname "*FooBar*" | tail -2 -exec cp "{}" dest \;
but the output was "invalid option --2" for tail.
Also, my file or directory name contains spaces.
The following should work on absolutely any paths.
Declare a function to be able to use head and tail on NUL-separated output:
nul_terminated() {
tr '\0\n' '\n\0' | "$@" | tr '\0\n' '\n\0'
}
Then you can use it to get a NUL-separated list of paths from your search after passing through tail:
find . -exec printf '%s\0' {} \; | nul_terminated tail -n 2
You can then pipe that to xargs and add your options:
find . -iname "*FooBar*" -exec printf '%s\0' {} \; | nul_terminated tail -n 2 | xargs -I "{}" -0 cp "{}" "dest"
Explanation:
find files in the current directory (.) and below with a name containing foobar (case insensitive because of the i in -iname);-exec) a command to{}) followed by a NUL character (\0) individually (\;);tr '\0\n' '\n\0');"tail -n 2, "$@");tr '\0\n' '\n\0').The xargs command is a bit harder to explain. It builds as many cp ... "dest" commands as necessary to fit in the maximum command length of the operating system, replacing the {} token in the command with the actual file name (-I "{}" ... "{}"), using the NUL character as a separator when reading the parameters (-0).
You can try
cp $(find . -iname "*FooBar*" | tail -2 ) dest
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With