Copy all *.txt to *.new.txt but ignore existing *.new.txt files - bash

I need script for this:
Copy all *.txt to *.new.txt
When run this script, ignore all *.new.txt files.
What I try:
find ~/folder -type f -name "*.txt" ! -name "*.new.txt"
how to send this output to
cp STDIN *.new.txt

Use -exec to execute a subshell where you copy the file to the modified filename.
find ~/folder -type f -name "*.txt" ! -name "*.new.txt" -exec bash -c 'cp "$1" "${1/.txt/.new.txt}"' {} {} \;

Related

Find file and cd into it

I am attempting to find multiple files, then quit after the first match and then cd into this match, I have attempted:
find `pwd` -iname 'tensorflow' -type d -exec echo {} \; -quit | xargs -I{} cd {}
However, this does nothing and it won't enter into that directory.
There is no /usr/bin/cd, it's not an executable. You have to run it in current shell, not in subshell as part of pipeline.
Do not use backticks. Prefer $(...).
find pwd? Just find ., you are already in pwd.
-exec echo {} \;? Just -print it.
dir=$(find . -iname 'tensorflow' -type d -print -quit)
cd "$dir"

"find" command with a variable directory

I'm trying to list the files in a directory that is given by the variable DIR. My code looks like this so far:
for i in `find $DIR -name "*.txt"
The variable DIR is already defined. I'm not sure what the syntax is here.
ls "${DIR}/*.txt"
or
find "${DIR}" -name "*.txt"
should do the trick. The first one only lists *.txt files in the directory itself, the second one also *.txt files in subdirectories.
I guess you want to execute a given action on all files with extension "txt" under $DIR and/or its subdirs. As usual there are different solutions.
This one:
$ for i in $(find "$DIR" -name \*.txt) ; do echo "Do something with ${i}" ; done
won't work if file path (either the file itself or one subdirectory) contains spaces.
But you can use this:
$ find "$DIR" -type f -name \*.txt | while read i ; do echo "Do something with ${i}" ; done
or this:
$ find "$DIR" -type f -name \*.txt -print0 | xargs -0 -I {} echo "Do something with {}"
or this:
$ find "$DIR" -type f -name \*.txt -exec echo "Do something with {}" \;
or... 100 additional solutions.
Not sure what you want.
find $DIR -name "*.txt" -print
will list all the files that end with .txt and are located in $DIR or its subdirectories. You can omit the -print as that is the default behaviour anyway.
If you have a simple thing you want to do with this file, you can use find's -exec function:
find $DIR -name "*.txt" -exec wc -l {} \;
Or you can use a loop:
for f in `find $DIR -name "*.txt"`; do
wc -l $f
mv $f /some/other/dir/
fi
note: as #mauro helpfully pointed out, this will not work if the DIR or the file names contain spaces.
Cheers

How to print the deleted file names along with path in shell script

I am deleting the files in all the directories and subdirectories using the command below:
find . -type f -name "*.txt" -exec rm -f {} \;
But I want to know which are the files deleted along with their paths. How can I do this?
Simply add a -print argument to your find.
$ find . -type f -name "*.txt" -print -exec rm -f {} \;
As noted by #JonathanRoss below, you can achieve an equivalent result with the -v option to rm.
It's not the scope of your question, but more generally it gets more interesting if you want to delete directories recursively. Then:
a simple -exec rm -r argument keeps it silent
a -print -exec rm -r argument reports the toplevel directories you're operating on
a -exec rm -rv argument reports all you're removing

removing files that have extension .bin then printing bye

filename=file.bin
extension=$(echo ${filename}|awk -F\. '{print $2}')
if [ ${extension} == "bin" ]; then
rm *.extenstion
fi
would something like this work how do I delete all files that have the same extention in a folder
You don't need to extract the extension yourself, this is what globbing is for. Simply do:
rm *.bin
Or recursively find ./ -name "*.bin" -exec rm -f {} \;
Aside from globbing, this is also doable with find.
find -type f -name "*.bin" -exec rm {} \;
Or more efficiently, with newer version of find:
find -type f -name "*.bin" -exec rm {} +
which is equivalent to
find -type f -name "*.bin" | xargs rm
Note: by default, find will do it recursively.

using find with exec

I want to copy files found by find (with exec cp option) but, i'd like to change name of those files - e.g find ... -exec cp '{}' test_path/"test_"'{}' , which to my test_path should copy all files found by find but with prefix 'test'. but it ain't work.
I'd be glad if anyone could give me some ideas how to do it.
best regards
for i in `find . -name "FILES.EXT"`; do cp $i test_path/test_`basename $i`; done
It is assumed that you are in the directory that has the files to be copied and test_path is a subdir of it.
if you have Bash 4.0 and assuming you are find txt files
cd /path
for file in ./**/*.txt
do
echo cp "$file" "/test_path/test${file}"
done
of with GNU find
find /path -type f -iname "*.txt" | while read -r -d"" FILE
do
cp "$FILE" "test_${FILE}"
done
OR another version of GNU find+bash
find /path -type f -name "*txt" -printf "cp '%p' '/tmp/test_%f'\n" | bash
OR this ugly one if you don't have GNU find
$ find /path -name '*.txt' -type f -exec basename {} \; | xargs -I file echo cp /path/file /destination/test_file
You should put the entire test_path/"test_"'{}' in ""
Like:
find ... -exec cp "{}" "test_path/test_{}" \;
I would break it up a bit, like this;
for line in `find /tmp -type f`; do FULL=$line; name=`echo $line|rev|cut -d / -f -1|rev` ; echo cp $FULL "new/location/test_$name" ;done
Here's the output;
cp /tmp/gcc.version new/location/test_gcc.version
cp /tmp/gcc.version2 new/location/test_gcc.version2
Naturally remove the echo from the last part, so it's not just echo'ng what it woudl of done and running cp

Resources