- Write output out of grep into a file on Linux?
- 8 Answers 8
- Shell bash find output to file
- Shell — modifying the find command output
- Combine linux `find` and `cp` with output if file is not found
- Output to variable or file using (find with -exec and shred)
- Unix Find Passing Filename to Exec and In Output Redirect
Write output out of grep into a file on Linux?
@Shawn, that’s not true: the > redirection is for xargs, not each grep it runs, so all greps write to the same output file.
8 Answers 8
How about appending results using >> ?
find . -name "*.php" | xargs grep -i -n "searchstring" >> output.txt
I haven’t got a Linux box with me right now, so I’ll try to improvize.
the xargs grep -i -n «searchstring» bothers me a bit.
Perhaps you meant xargs -I <> grep -i «searchstring» <> , or just xargs grep -i «searchstring» ?
Since -n as grep’s argument will give you only number lines, I doubt this is what you needed.
This way, your final code would be
find . -name "*.php" | xargs grep -i "searchstring" >> output.txt
@Rajesh: then your first part sounds problematic. You should write your code iteratively, so you can see what’s really happening. In this case, you should have tried find . -name «*.php» to see if you get any results. What happens if you try find . -name «*php» -type f ?
You can use grep —include=*.php . to filter by extension in order to avoid the find | xargs ugliness
find . -name "*.php" -exec grep -i -n "function" <> \; >output.txt
But you won’t know what file it came from. You might want:
find . -name "*.php" -exec grep -i -Hn "function" <> \; >output.txt
grep: <>: No such file or directory grep: ;: No such file or directory
I guess that you have spaces in the php filenames. If you hand them to grep through xargs in the way that you do, the names get split into parts and grep interprets those parts as filenames which it then cannot find.
There is a solution for that. find has a -print0 option that instructs find to separate results by a NUL byte and xargs has a -0 option that instructs xargs to expect a NUL byte as separator. Using those you get:
find . -name "*.php" -print0 | xargs -0 grep -i -n "searchstring" > output.txt
I ran your original command on my box and it seems to work fine, so I’m not sure anymore.
Looks fine to me. What happens if you remove >output.txt ?
If you’re searching trees of source code, please consider using ack. To do what you’re doing in ack, regardless of there being spaces in filenames, you’d do:
ack --php -i searchstring > output.txt
Shell bash find output to file
I am sure there are alternative solutions and am open to those #will tell you if a file is not found or the location of the file if found: command: output: file1_L001_R*_001.fastq.gz — file not found ./file2_S13_L001_R2_001.fastq.gz ./file2_S13_L001_R1_001.fastq.gz file3_L001_R*_001.fastq.gz — file not found #will copy files found to new directory Any suggestions Solution: Write a script that receives the filename to copy on its standard input. The message does not have to exclusively say a file is not found; it can also include the location of files that are found like the output displayed below.
Shell — modifying the find command output
Is there anyway to print and output to a find command without listing the directory of the find in your output? meaning if I issue
find /home/people/name -type f -name >> /output/log/output.txt
the output in the log is written as:
/home/people/name/filename1.txt /home/people/name/filename2.txt /home/people/name/filename3.txt
what I want is the just the file name without the directory name? is that possible?
By default, as you saw, find prints full paths:
$ find /home/people/name -type f /home/people/name/filename1.txt /home/people/name/filename3.txt /home/people/name/filename2.txt
find , however, does offer control over the output using -printf . To get just the filename, with no path, try:
$ find /home/people/name -type f -printf '%f\n' filename1.txt filename3.txt filename2.txt
%f tells find that you want the filename without the path. \n tells find that you want a newline after each filename.
The output can, of course, be saved in a file:
$ find /home/people/name -type f -printf '%f\n' >output.txt $ cat output.txt filename1.txt filename3.txt filename2.txt
Redirect output to multiple files in a specific directory in for loop shell, Make the output file depend on $f . #!/bin/bash FILES=»/home/yha/AG2R/*» target_dir=/home/yha/AG2R/COPY for f in $FILES do echo «Processing
Combine linux `find` and `cp` with output if file is not found
I would like to take an input text file (one line per file to find) to do two things: copy the files that are found to a different directory and provide a message whether the file is not found. The message does not have to exclusively say a file is not found; it can also include the location of files that are found like the output displayed below. I have not been able to combine the two commands below. Is this possible? I am sure there are alternative solutions and am open to those
#will tell you if a file is not found or the location of the file if found: command:
for i in $(cat toGet.txt); do find . -name «$i» | grep . || echo «$i — file not found» ; done
- file1_L001_R*_001.fastq.gz — file not found
- ./file2_S13_L001_R2_001.fastq.gz
- ./file2_S13_L001_R1_001.fastq.gz
- file3_L001_R*_001.fastq.gz — file not found
#will copy files found to new directory
for i in $(cat toGet.txt); do find . -name «$i» -exec cp <> /path/to/directory \; ; done
Write a script that receives the filename to copy on its standard input. If the input is empty, it reports that the file is not found, otherwise it copies it. Then pipe the find output to it.
#!/bin/sh looking_for=$1 dest_dir=$2 found=$(cat) if [ -z "$found" ] then echo "$looking_for - file not found" else cp "$found" "$dest_dir"
while read -r i; do find . -name "$i" | ./copy_to.sh "$i" /path/to/directory done < toGet.txt
How To Combine File Names From find Output Into A String, Thank you in advance for your consideration and response. bash shell-script find · Share.
Output to variable or file using (find with -exec and shred)
I have a find command that I exec to shred and it works great; however, I need to capture the output of this and pass to a variable or a file. I have tried so many iterations of the below commands, but cant seem to get it to work. I also have tried for loops. It always will display to my terminal as it goes through the shred process, but never writes to a file or variable. I would prefer a variable but will take anything at this point. Please see my examples below:
Original find command:
find /burncd/working -type f -exec shred -v -n7 -z --remove <> \;
Latest try at a command to pass to a file (from StackExchange):
find /burncd/working/* -type f -exec bash -c 'shred -v -n7 -z --remove "$1" /tmp/find.out' $0 <> \;
I would appreciate any help you could give.
shred seems to output the progress status to stderr and not stdout, so you need to use the 2> or 2>> for redirecting that output.
Something like this would redirect the stderr of both find and shred:
find . -type f -exec shred -n1 -v <> + 2> /tmp/shred.out
And this would redirect just the stderr of shred :
> ../shred.out find . -type f -exec sh -c 'shred -n1 -v "$@" 2>> /tmp/shred.out' find-sh <> +
(The shell that find starts gets find-sh and the filenames as arguments, find-sh goes to $0 , the filenames to $1 , $2 . all of which "$@" expands as distinct words. The string that goes to $0 can be arbitrary, but it helps to be somewhat descriptive since it may be used in error messages.)
Also you could do something like this to get the output of find and shred to both the file and the terminal:
find . -type f -exec shred -n1 -v <> + 2>&1 | tee /tmp/shred.out
(Similarly find .. -exec sh -c 'shred . 2>&1 | tee /tmp/shred.out' find-sh <> + should work to only put the output of shred through tee . Though back-to-back outputs from find and shred could get mixed in the wrong order if you do that.)
Assign result of find command to a list variable in bash script, Closed 2 years ago. I have a base directory with a set of subdirs inside, some of those dirs have files with extension of jpg. I want
Unix Find Passing Filename to Exec and In Output Redirect
I want to base64 encode a directory of images removing newlines in the base64 output. I then save this as .base64.txt .
I can do this using the following for loop:
for file in $(find path/to/images -name "*.png"); do base64 "$file" | tr -d "\n" > "$file".base64.txt done
How would I do this with find using xargs or -exec ?
This is very closely a dupe of How do I include a pipe | in my linux find -exec command?, but does not cover the case you are dealing with.
To get the filename, you can run a -exec sh -c loop
find path/to/images -name "*.png" -exec sh -c ' for file; do base64 "$file" | tr -d "\n" > "$.base64.txt" done' _ <> +
Using find -exec with + puts all the search results from find in one shot to the little script inside sh -c '..' . The _ means invoke an explicit shell to run the script defined inside '..' with the filename list collected as arguments.
An alternate version using xargs which is equally expensive as the above loop would be to do below. But this version separates filenames with NUL character -print0 and xargs reads it back delimiting on the same character, both GNU specific flags
find path/to/images -name "*.png" -print0 | xargs -0 -I <> sh -c 'base64 <> | tr -d "\n" > <>.base64.txt'
I want to get an output of the find command in shell script, 1 Answer 1 You are overwriting the file in each iteration. You can use xargs to perform find on multiple directories; but you have to use an