How to get file size in byte using wc -c - linux

when I use the command to get the file size in bye using wc -c the command return two values, the size in byte and the file name, ex:
the output for wc -c my_file is 322 my_file
I need to get only the first value to use it if condition, and I need to use this specific command not any other one..
Any help please, thank you.

Redirect stdin and wc wont know or echo the file name
wc -c < my_file

This can also be done without redirection or wastefully reading the whole file using stat:
stat -c %s my_file

Related

How can I loop through a directory and get wc of every txt file?

The shell is sh.
I have been using a for loop:
for F in *.txt
do
echo `wc -w $F`
done
This has been returning the number of words and the name of the file. I don't understand why it keeps returning the name of the file; it looks like it should only return the number of words in the file.
This is the default behavior of wc, it shows the filename after the count.
If you just want the count, pass the filename via STDIN:
wc -w <filename
Also, without iterating over the files using for, you could just use globbing for getting the filenames at once, wc takes multiple arguments so there would not be a problem:
wc -w *.txt
In this case, to get rid of the filenames, use some text-processing:
wc -w *.txt | awk '{print $1}'
This should be faster than the fora approach you have already.

grep - limit number of files read

I have a directory with over 100,000 files. I want to know if the string "str1" exists as part of the content of any of these files.
The command:
grep -l 'str1' * takes too long as it reads all of the files.
How can I ask grep to stop reading any further files if it finds a match? Any one-liner?
Note: I have tried grep -l 'str1' * | head but the command takes just as much time as the previous one.
Naming 100,000 filenames in your command args is going to cause a problem. It probably exceeds the size of a shell command-line.
But you don't have to name all the files if you use the recursive option with just the name of the directory the files are in (which is . if you want to search files in the current directory):
grep -l -r 'str1' . | head -1
Use grep -m 1 so that grep stops after finding the first match in a file. It is extremely efficient for large text files.
grep -m 1 str1 * /dev/null | head -1
If there is a single file, then /dev/null above ensures that grep does print out the file name in the output.
If you want to stop after finding the first match in any file:
for file in *; do
if grep -q -m 1 str1 "$file"; then
echo "$file"
break
fi
done
The for loop also saves you from the too many arguments issue when you have a directory with a large number of files.

How do I use the pipe command to display attributes in a file?

I'm currently making a shell program and I want to display the total amount of bytes in a specific file using the pipe command. I know that the pipe command takes whatever is on the left side and gives it to the right as input. (Assuming you are in the directory the file is in)
I know that the command (wc -c) displays the number of bytes in a file but I'm not sure how to pipe it. What I've tried was:
ls fileName.sh | wc -c
wc takes the filename as argument, not as input. Try this:
wc -c fileName.sh
The wc program takes multiple arguments. You can do this to apply it to all entries in the current working directory:
wc -c $(ls)
Another approach is to use xargs to convert input to arguments:
ls | xargs wc -c
You may need to use a more complex line if you have spaces in your filenames. ls can output a single file per line, and xargs can be told to split only on \n:
ls -1 | xargs -d '\n' wc -c
If you prefer to use find instead of ls (a more powerful tool), the -print0 option for find plays along with the -0 option to xargs.

Searching for a specifc given hex string in multiple images on Linux

I am doing some research on image processing and I wanted to know if its possible to search for a specific hex string/byte array in various images. It would be great if it gives me a list of images that has that specific string. Basically what grep -r "" does. For some reason grep doesn't do the job. I am not familiar with strings. I did had a look at "man strings" but it didn't help much. Anyways, I would like to look for a specific hex string say "0002131230443" (or even specific byte array i.e. base64 string) in several images in the same folder. Any help would be highly appreciated.
I found this code which exactly does what I want using xxd and grep. Please find the command below:
xxd -p /your/file | tr -d '\n' | grep -c '22081b00081f091d2733170d123f3114'
FYI:
It'll return 1 if the content matches, 0 else.
xxd -p converts the file to plain hex dump, tr -d '\n' removes the newlines added by xxd, and grep -c counts the number of lines matched.
Does anyone know how to run the code above in a specific directory using bash script. I have around 400 images and I want it to return only 400 (i.e. a string matching count) if all the 400 images have that particular string. I found this script code below but it runs the same code over and over for 400 times returning either 0 or 1 each time:
#!/bin/bash
FILES=/FILEPATH/*
for f in $FILES
do
echo "PROCESSING $f FILES"
echo "-------------------"
XXD -u $f | grep ABCD
echo "-------------------"
done
Thanks guys.
Plasma33
With GNU grep:
#!/bin/bash
files=/FILEPATH/*
for f in $files
do
grep -m 1 -P '\x22\x08\x1b\x00' < "$f"
done | wc -l

Ambiguous Redirection on shell script

I was trying to create a little shell script that allowed me to check the transfer progress when copying large files from my laptop's hdd to an external drive.
From the command line this is a simple feat using pv and simple redirection, although the line is rather long and you must know the file size (which is why I wanted the script):
console: du filename (to get the exact file size)
console: cat filename | pv -s FILE_SIZE -e -r -p > dest_path/filename
On my shell script I added egrep "[0-9]{1,}" -o to strip the filename and keep just the size numbers from the return value of du, and the rest should be straightforward.
#!/bin/bash
du $1 | egrep "[0-9]{1,}" -o
sudo cat $1 | pv -s $? -e -r -p > $2/$1
The problem is when I try to copy file12345.mp3 using this I get an ambiguous redirection error because egrep is getting the 12345 from the filename, but I just want the size.
Which means the return value from the first line is actually:
FILE_SIZE
12345
which bugs it.
How should I modify this script to parse just the first numbers until the first " " (space)?
Thanks in advance.
If I understand you correctly:
To retain only the filesize from the du command output:
du $1 | awk '{print $1}'
(assuming the 1st field is the size of the file)
Add double quotes to your redirection to avoid the error:
sudo cat $1 | pv -s $? -e -r -p > "$2/$1"
This quoting is done since your $2 contains spaces.

Resources