Reputation: 315
I'm trying to append a string into a file if the file exists and if it is not already in it. Otherwise, create the file with the string in it.
if [ -f PATH_TO_FILE ]; then
if ! grep -q PATTERN PATH_TO_FILE; then
echo STRING >> PATH_TO_FILE
fi
else
echo STRING >> PATH_TO_FILE
fi
I want to optimize that with AND/OR conditions in the if statements but struggle with the syntax.
I tried to do the following but it does not work if the file does not exist.
grep -q PATTERN PATH_TO_FILE || echo STRING >> PATH_TO_FILE
Can anyone help me finding the sweetest syntax?
Upvotes: 2
Views: 2561
Reputation: 22428
This can be done like this too:
[ ! -f PATH_TO_FILE ] || ! grep -q PATTERN PATH_TO_FILE && echo STRING >> PATH_TO_FILE
Explanation:
At first it checks for existing file. If it doesn't exist, the first condition is true
and thus the miidle part (grep
) is skipped and echo
part is executed, i.e file is created with STRING in it.
And if the file exist, the first condition is false, thus second condition is executed, and the echo
part executes only if the grep
part is true
. Thus if the PATTERN
matches, the echo
part won't be executed i.e STRING
won't be written in the file if PATTERN matches.
Example:
[ ! -f PATH_TO_FILE ] || ! grep -q STRING PATH_TO_FILE && echo STRING >> PATH_TO_FILE
[ ! -f PATH_TO_FILE ] || ! grep -q STRING PATH_TO_FILE && echo STRING >> PATH_TO_FILE
This will create a file named PATH_TO_FILE and write STRING in it. Even though the same code is executed two times, it won't write STRING twice. Because at second time, STRING is found in PATH_TO_FILE.
And if you execute it with a second STRING and PATTERN it will write to it:
[ ! -f PATH_TO_FILE ] || ! grep -q STRING2 PATH_TO_FILE && echo STRING2 >> PATH_TO_FILE
STRING2 will be appended to the file.
Upvotes: 0
Reputation: 785058
You can do:
if [[ ! -f PATH_TO_FILE ]] || ! grep -q PATTERN PATH_TO_FILE; then
echo STRING >> PATH_TO_FILE
fi
Upvotes: 3
Reputation: 121377
This
grep -q PATTERN PATH_TO_FILE || echo STRING >> PATH_TO_FILE
does the equivalent functionality as the if ..else
statements.
So, if you don't like to see the error message when the file doesn't exist, you could redirect stderr
to /dev/null
.
grep -q PATTERN PATH_TO_FILE 2>/dev/null || echo STRING >> PATH_TO_FILE
Upvotes: 4