I have a question and i would be grateful for the answer if somebody knows one.
Ok, to the point. In one of my scripts i have following expression, it is not clear for me form man page what effect it should produce:
if ! [[ -s "$the_file_to_check" ]] ; then echo "file is zero sized and not exist | is exist and zero sized | not zero sized and not exist | not zero sized or not exist | not exist (obviously zero sized)" ; fi
there exist separate check for existence (the -a key), why to add another one?
And how this logics works in anyway.
I little bit lost in definition.
P.S.
I need a check for emptiness but not existence. Thank everyone.
-s checks not only if the file exists, but also if it contains any data (that is, if it has a size greater than 0 bytes). This is more than the -a option (which is, in fact, a synonym of -e) does, which only tests if the file exists.
touch foo
[[ -a foo ]] && echo "File foo exists"
[[ -s foo ]] || echo "File foo exists, but is size 0 bytes"
(I have wondered what the rationale for -a is, since I'm not aware that it does anything different from -e.)
This if command simply prints the string file is zero sized and not exist | is exist and zero sized | not exist (obviously zero sized) if the file does not exist or if the file is zero sized.
If you want your if command to check only for the zero sized file and not file existence then you can do something like this :
if [[ $(du -h "$the_file_to_check" |cut -f 1) == "0" ]] ;then
echo "file is zero sized" ;
fi
But this if statement will post a error if file does not exist. Make sure you execute this only when the file is present.
Related
I know I can specify the tab-width for all documents and I can have Atom auto-detect the usage of tab characters versus spaces but is there any way to auto-detect tab-width?
I am working with files that use both 2-space width and 4-space width. Combined with how Atom interacts with tabs (automatically prepending multiples of four when I make a new line and treating four contiguous spaces as a single character) this makes for a pretty frustrating experience.
Is there any simple way of having Atom switch between 4- and 2-width tabs automatically?
I put together a script for converting files from one tab-width to another. (Assuming "tabs" are spaces.)
I think the first few lines describe its usage well enough but just in case; the first argument must specify the file's current tab-width. (You'll have to check this yourself.) The second argument specifies the desired tab-width. Third argument is the filename and the final argument is the destination for the modified file.
E.g. To change from 2-width to 4.
chtabwidth 2 4 "./file.py" "./moddedFile.py"
Note: Do not save the file to itself. It appends to the end of the file it is reading and will run forever. (This was the first thing I did and I made a 20MB file before I realized why it was hanging.) Actually, you know what, I'll add a condition to ensure it never happens. There, done.
#!/bin/bash
old_width="$1"
new_width="$2"
file="$3"
newfile="$4"
if [[ "$file" == "$newfile" ]]; then
echo "Don't save to the same file!!"
exit
fi
IFS=
while read -r p || [[ -n $p ]]; do
indent_len=$(echo "$p" | egrep -o "^ *" | tr -d '\012\015' | wc -m)
tab_num=$(( indent_len / old_width ))
new_indent_len=$(( tab_num * new_width ))
new_indent=$(printf '%*s' $new_indent_len '')
revised=$(echo ${new_indent}$(echo "$p" | egrep -o "[^ ].*$"))
echo "$revised" >> "$newfile"
done <"$file"
PS. I hate bash programming.
PPS. Zero warranty; don't blame me if random code you downloaded from the Internet sets your lunch on fire.
What i'm trying to do basically is to get the folder size and check if it's greater than X size to do some actions (move files externally)...but the conditionnal doesn't work.
#!/bin/bash
FOLDER_SIZE="5709119"
CHECK=$(du -s /var/backups/ | cut -f1)
echo "Current folder size $CHECK"
echo "Current SIZE LIMIT $FOLDER_SIZE"
if [[ $CHECK -gt $FOLDER_SIZE ]]
then
echo "$CHECK BIGGER THAN $FOLDER_SIZE"
else
echo "$CHECK SMALLER THAN $FOLDER_SIZE"
fi
The problem here is: i'm always getting the size of $check is smaller than $folder_size which not true since the $CHECK folder is mucher bigger than 5GB.
I'm getting as well this error when i run the script:
bk_script.sh: 35:bk_script.sh: [[: not found
Any hints will be much appreciated.
bk_script.sh: 35:bk_script.sh: [[: not found
How are you running your script? The error suggests you're doing something like sh bk_script.sh rather than ./bk_script.sh. Always do the latter so it uses the declared shell /bin/bash rather than /bin/sh. Plain sh does not have a [[ operator.
I need help. I should write a script,whih will move all non-ASCII files from one directory to another. I got this code,but i dont know why it is not working.
#!/bin/bash
for file in "/home/osboxes/Parkhom"/*
do
if [ -eq "$( echo "$(file $file)" | grep -nP '[\x80-\xFF]' )" ];
then
if test -e "$1"; then
mv $file $1
fi
fi
done
exit 0
It's not clear which one you are after, but:
• To test if the variable $file contains a non-ASCII character, you can do:
if [[ $file == *[^[:ascii:]]* ]]; then
• To test if the file $file contains a non-ASCII character, you can do:
if grep -qP '[^[:ascii:]]' "$file"; then
So for example your code would look like:
for file in "/some/path"/*; do
if grep -qP '[^[:ascii:]]' "$file"; then
test -d "$1" && mv "$file" "$1"
fi
done
The first problem is that your first if statement has an invalid test clause. The -eq operator of [ needs to take one argument before and one after; your before argument is gone or empty.
The second problem is that I think the echo is redundant.
The third problem is that the file command always has ASCII output but you're checking for binary output, which you'll never see.
Using file pretty smart for this application, although there are two ways you can go on this; file says a variety of things and what you're interested in are data and ASCII, but not all files that don't identify as data are ASCII and not all files that don't identify as ASCII are data. You might be better off going with the original idea of using grep, unless you need to support Unicode files. Your grep is a bit strange to me so I don't know what your environment is but I might try this:
#!/bin/bash
for file in "/home/osboxes/Parkhom"/*
do
if grep -qP '[\0x80-\0xFF]' $file; then
[ -e "$1" ] && mv $file $1
fi
done
The -q option means be quiet, only return a return code, don't show the matches. (It might be -s in your grep.) The return code is tested directly by the if statement (no need to use [ or test). The && in the next line is just a quick way of saying if the left-hand side is true, then execute the right-hand side. You could also form this as an if statement if you find that clearer. [ is a synonym for test. Personally if $1 is a directory and doesn't change, I'd check it once at the beginning of the script instead of on each file, it would be faster.
If you mean you want to know if something is not a plain text file then you can use the file command which returns information about the type of a file.
[[ ! $( file -b "$file" ) =~ (^| )text($| ) ]]
The -b simply tells it not to bother returning the filename.
The returned value will be something like:
ASCII text
HTML document text
POSIX shell script text executable
PNG image data, 21 x 34, 8-bit/color RGBA, non-interlaced
gzip compressed data, from Unix, last modified: Mon Oct 31 14:29:59 2016
The regular expression will check whether the returned file information includes the word "text" that is included for all plain text file types.
You can instead filter for specific file types like "ASCII text" if that is all you need.
The finished product is meant to recursively count everything in a specified directory, or the current if no arguments are entered. Right now Im just trying to get it to count anything in the specified directories. I'm having difficulty getting the last statements to count anything at all.
It will echo 0 files in the directory.
Could anyone give me any tips? I'm still a beginner so take it easy on me, thanks!
#!/bin/bash
#A shell script program that counts recursively how many directories/files exist in a given directory.
declare -i COUNT=0
declare -i COUNT2=0
#The script will treat COUNT as an integer that is 0 until modified.
if [ "$#" -eq "0" ]
then
for i in *
do
((COUNT++))
done
((COUNT--)) #This is done because there is always an overcount of 1.
echo "There are $COUNT files and/or directories in the current directory here."
fi
if [[ -d $1 ]]
then
for i in $1
do
((COUNT++))
done
((COUNT--)) #This is done because there is always an overcount of 1.
echo "There are $COUNT files and/or directories in $1."
fi
if [[ -d $2 ]]
then
for i in $2
do
((COUNT2++))
done
((COUNT2--)) #This is done because there is always an overcount of 1.
echo "There are $COUNT2 files and/or directories in $2."
fi
exit 0
First of, you can do what you want with a one-liner:
find . | wc -l
find . means "search in the current directory and all subdirectories". Since there is no other argument, it will simple list everything. Then, I use a pipe and wc, which stands for "word count". The -l option means "output only the number of lines".
Now, for your code, here are some tips. First, I don't really understand why you repeat your code three times (for 0, $1 and $2). You could simply do:
dir="$1"
if [ -z "$dir" ]; then dir="."; fi
You store the value of the command-line argument in $dir and if none is provided, (-z means "is empty"), you assign a default value to dir.
for i in $1 won't work if $1 is the path to a directory. So instead, you can use
for i in $(ls $dir)
Also, in your code, you don't count recursively. Is it voluntary or you don't know how to proceed ?
One of our suppliers has a buggy shop floor system (long story short). While they fix whatever is wrong on their end, I need to segregate files they send: they are not empty but have a long empty string. Typically a good file will look like this in vi
<insert_list><test_event_insert endTime="2012-09-10T05:28:45" startTime="2012-09-10T05:27:41" operator="8176967"><process_step name="FVT" revision="NO DATA"></process_step><location1 name="CT" type="REGION"><location2 name="ONTREP1" type="TESTER"><location3 name="LineA" type="LINE"></location3></location2></location1><unit ...
"CT~DCA~FVT~8176967~ONTREP1~4~P~1100~DECA1MR0-01~XED1B1033A4675~20120910~052846.XML" [noeol][dos] 3L, 2170C
a bad file will look this:
^#^#^#^#^#^#^#^#^#^#^#^#^#...
"CT~DCA~FVT~8176967~ONTREP1~2~P~1100~DECA1MR0-01~XED1B1045B6072~20120904~043209.XML" [noeol] 1L, 2170C
The caret/at sign combo is VI's interpretation of that string, I guess but it is in fact an empty string. Using -z seems to work on one single file
X=CT~DCA~FVT~8176967~ONTREP1~2~P~1100~DECA1MR0-01~XED1B1045B6072~20120904~043209.XML
if [ ! -z $X ]
then
echo "$X empty"
else
echo "$X not empty"
fi
CT~DCA~FVT~8176967~ONTREP1~2~P~1100~DECA1MR0-01~XED1B1045B6072~20120904~043209.XML empty
But the same code is telling me that all 900 files on my EMC mass filer are empty. Which is not true.
export OUT=/path/to/device
declare -a myArray
for f in "$OUT"/*ONTREP1*; do myArray+=( "${f#$OUT/}" ); done
for i in "${myArray[#]}"; do if [ ! -z $i ] ; then echo "$i empty"; else echo "$i not empty"; fi; done
NB: Pattern "ONTREP1" is to narrow down the faulty files to one shop floor computer name.
What am I missing?
You are missing that test -z string tests whether a string is empty (as opposed to test -s file which tests whether a file is empty.) Furthermore the ^# in vim are an indication of NUL bytes--bytes with the value 0. It looks like these are binary data files or maybe corrupted, but certainly not empty. An empty file in vim displays as all tildes (~) in the leftmost column :-)
Try running the file filename command on the good and bad files; the latter probably says "data" due to the NUL bytes.