Add a Newline Only If It Doesn't Exist

Add a newline only if it doesn't exist

Since it removes newline if it's not there, you could simply use:

echo "" >> file;  sed -ie '/^$/d;$G' file; sed -ie '/^$/d;$G' file

Adds a newline and removes everything then adds newline. Not the elegant way, but certainly works :)

Appending a line to a file only if it does not already exist

Just keep it simple :)

grep + echo should suffice:

grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
  • -q be quiet
  • -x match the whole line
  • -F pattern is a plain string
  • https://linux.die.net/man/1/grep

Edit:
incorporated @cerin and @thijs-wouters suggestions
.

how to add a new line in a text file using python without \n

Your question doesn't actually make sense, because of what a "line" actually is and what that '\n' character means.

Files don't have an intrinsic concept of lines. A file is just a sequence of bytes. '\n' is the line separator (as Python represents it with universal newlines). If you want your data to show up on different "lines", you must put a line separator between them. That's all that the '\n' character is. If you open up the file in a text editor after you write it, most editors won't explicitly show the newline character by default, because it's already represented by the separation of the lines.


To break down what your code is doing, let's look at the add method, and fix some things along the way.

The first thing add does is name a variable called nl and assign it the newline character. From this, I can surmise that nl stands for "newline", but it would be much better if that was actually the variable name.

Next, we name a variable called acc and assign it the '.acc' suffix, presumably to be used as a file extension or something.

Next, we make a variable called xy and assign it to x + acc. xy is now a string, though I have no idea of what it contains from the variable name. With some knowledge of what x is supposed to be or what these lines represent, perhaps I could rename xy to something more meaningful.

The next three lines create three new variables called exyz, xyz, and xxx, and point them all to the same string that xy references. There is no reason for any of these lines whatsoever, since their values aren't really used in a meaningful way.

Now, we open a file. Fine. Maybe tf stands for "the file"? "text file"? Again, renaming would make the code much more friendly.

Now, we call tf.writelines(nl). This writes the newline character ('\n') to the file. Since the writelines method is intended for writing a whole list of strings, not just a single character, it'll be cleaner if we change this call to tf.write(nl). I'd also change this to write the newline at the end, rather than the beginning, so the first time you write to the file it doesn't insert an empty line at the front.

Next, we call writelines again, with our data variable (xxx, but hopefully this has been renamed!). What this actually does is break the iterable xxx (a string) into its component characters, and then write each of those to the file. Better replace this with tf.write(xxx) as well.

Finally, we have tf.close, which is a reference to the close function of the file object. It's a no-op, because what you presumably meant was to close the file, by calling the method: tf.close(). We could also wrap the file up as a context manager, to make its use a little cleaner. Also, most of the variables aren't necessary: we can use string formatting to do most of the work in one step. All in all, your method could look like this at the end of the day:

def add(x):
with open('accounts.dat',"a+") as output_file:
output_file.write('{0}.acc\n'.format(x))

So you can see, the reason the '\n' appears at the end of every line is because you are writing it between each line. Furthermore, this is exactly what you have to do if you want the lines to appear as "lines" in a text editor. Without the newline character, everything would appear all smashed together (take out the '\n' in my add method above and see for yourself!).


The problem you described in the comment is happening because names is a direct reading of the file. Looking at the readlines documentation, it returns a list of the lines in the file, breaking at each newline. So to clean those names up, you want line 4 of the code you posted to call str.strip on the individual lines. You can do that like this:

names = tf.readlines()
for i in range(len(names)):
names[i] = names[i].strip() # remove all the outside whitespace, including \n

However, it's much cleaner, quicker, and generally nicer to take advantage of Python's list comprehensions, and the fact that file objects are already iterable line-by-line. So the expression below is equivalent to the previous one, but it looks far nicer:

names = [line.strip() for line in tf]

How do I add a line to a file in powershell if it doesn't exist?

All you need is to add the -SimpleMatch switch to your Select-String.

The reason this doesn't match as a regular expression is due to the parenthesis. Parenthesis mean grouping in regular expressions, and don't match literal parentheses in you file, resulting in an overall failure to match.

How to insert a newline in front of a pattern?

Some of the other answers didn't work for my version of sed.
Switching the position of & and \n did work.

sed 's/regexp/\n&/g' 

Edit: This doesn't seem to work on OS X, unless you install gnu-sed.

Insert a line after pattern match, if only the string does not exists

This could be done with awk, please try following. You can use it as a single code.

awk -v val="${version}" '
FNR==NR{
if($0~/cpu-management/){
found=1
}
next
}
/rover/ && found==""{
print $0 ORS "- cpu-management:" val
next
}
1
' Input_file Input_file

OR as per Ed sir's suggestion you could do following too use either above OR use following.

awk -v val="${version}" '
FNR==NR{
if($0~/cpu-management/){
found=1
}
next
}
{
print
}
/rover/ && !found{
print "- cpu-management:" val
}
' Input_file Input_file

For your shown samples output will be as follows:

Ranges:
- PeakK2:8.8.9
- rover-heal:3.3.1
- cpu-management:1.9.0
Arg: V1
change: 1

Explanation: Adding detailed explanation for above.

awk -v val="${version}"         ##Starting awk program from here.
FNR==NR{ ##Checking condition FNR==NR which will be treu when 1st time Input_file is being read.
if($0~/cpu-management/){ ##Checking condition if line contains cpu-management then do following.
found=1 ##Setting found to 1 here.
}
next ##next will skip all further statements from here.
}
/rover/ && found==""{ ##Checking if line has rover AND found is NULL then do following.
print $0 ORS "- cpu-management:" val ##Printing current line ORS with new value.
next ##next will skip all further statements from here.
}
1 ##Printing current line here.
' Input_file Input_file ##Mentioning Input_file name here.

Ansible: Insert line if not exists

The lineinfile module ensures the line as defined in line is present in the file and the line is identified by your regexp. So no matter what value your setting already has, it will be overridden by your new line.

If you don't want to override the line you first need to test the content and then apply that condition to the lineinfile module. There is no module for testing the content of a file so you probably need to run grep with a shell command and check the .stdout for content. Something like this (untested):

- name: Test for line
shell: grep -c "^couchbase.host" /database.properties || true
register: test_grep

And then apply the condition to your lineinfile task:

- name: add couchbase host to properties
lineinfile:
dest: /database.properties
line: couchbase.host=127.0.0.1
when: test_grep.stdout == "0"

The regexp then can be removed since you already made sure the line doesn't exist so it never would match.

But maybe you're doing things back to front. Where does that line in the file come from? When you manage your system with Ansible there should be no other mechanisms in place which interfere with the same config files. Maybe you can work around this by adding a default value to your role?

Create a .txt file if doesn't exist, and if it does append a new line

Use the correct constructor:

else if (File.Exists(path))
{
using(var sw = new StreamWriter(path, true))
{
sw.WriteLine("The next line!");
}
}


Related Topics



Leave a reply



Submit