Delete empty lines from a file - unix

I need to delete empty lines from a file (with spaces only - not null records).
The following command works only for null rows, but not in case of
spaces:
sed '/^$/d' filename
Can it be done using grep?

Use \s* for blank lines containing only whitespace:
sed '/^\s*$/d' file
To save the changes back to the file use the -i option:
sed -i '/^\s*$/d' file
Edit:
The regex ^\s*$ matches a line that only contains whitespace, grep -v print lines that don't match a given pattern so the following will print all none black lines:
grep -v '^\s*$' file

The POSIX portable way to do this is
sed -i '/^[[:blank:]]*$/d' file
or
grep -v '^[[:blank:]]*$' file

sed -i '/^[ \t]*$/d' file-name
it will delete all blank lines having any no. of white spaces (spaces or tabs) i.e. (0 or more)in the file..
NOte: there is a 'space' followed by '\t' inside the square bracket...
"-i" will force to write the updated contents back in the file... without this flag you can see the empty lines got deleted on the screen but the actual file will not be affected.

It happened that the file was copied from Windows machine a the sed command (sed '/^$/d' foo ) was not running correctly.
I ran following command and it worked.
$ dos2unix foo

Related

How to replace last word of a pattern matched line based on delimiters in a Unix file?

I have one file Backup_status.txt like below.
x01stestdb1a-10.92.201.111-SUCCESS
x01stestdb2a-10.92.201.112-SUCCESS
x01stestdb3a-10.92.201.113-SUCCESS
Backups running in all servers.
For ex, if backup filed in x01stestdb2a, we need to search with hostname x01stestdb2a in this file and change the status to FAIL.
Here i'm using hyphen(-) as delimiter.
Help me on how to search with that server name in the file and replace the last block using delimiter -.
NOTE: I want to change the content in the file.
Try this:
sed -i '/SERVER1/ s/-[^-]*$/-FAIL/' Backup_status.txt
/SERVER1/ let sed do the substitute on the line that matchs SERVER1.
The sed solution assume that the SUCCESS/FAIL is always in the last field, which may not be true. A more general solution is to use awk:
awk -i inplace -F'-' '/SERVER1/ {sub($3, "FAIL")}; {print}' Backup_status.txt
-i inplace is same as sed -i
-F'-' set the delimiter to '-'
/SERVER1/ {sub($3, "FAIL")}; replace the third field of lines that contain SERVER1 with "FAIL".
{print} print each line. For lines that contain SERVER1, it'll print the changed version, otherwise it'll print the line as it is.

How to add bracket at beginning and ending in text on UNIX

I have a text file of million lines to precess on UNIX as below:
"item"
"item"
"item"
"item"
And I use sed -i "s/$/,/g" filename > new_file to add comma at the end of each line.
What I expected is this way:
["item",
"item",
"item",
"item"]
Now, I am just using Vim to edit manually. Is there anyway to add brackets at the beginning and ending automatically with removing the comma at last line? So that, I could write a bash script to process these text files neatly.
Thanks!
sed -e '1s/^/[/' -e 's/$/,/' -e '$s/,$/]/' file_name > new_file
The only funny bit is replacing the comma added to the last line with the close square bracket.
Also note that using -i means there will be no output to standard output. Either use -i or use I/O redirection but not both. (And if you're a portability nut — like me — note that Mac OS X or BSD sed supports -i but requires a suffix for the backup. It will quite happily use -e as the suffix, if there's a -e after the -i, or use the sed script if you don't specify a -e — but then it complains about the file name not being a valid sed script).

SED command in UNIX

I want to remove below string from a file in Unix:
<?xml version='1.0' encoding='UTF-8'?>
The file content is exactly this:
<?xml version='1.0' encoding='UTF-8'?>Hello World
in one single continuous line.
I am using the following command to achieve the same:
sed s'/<?xml version='1.0' encoding='UTF-8'?>//g' myFile > myFile1
However, the resultant file myFile1 is still having the string.
How to achieve this ?
Given that it's the XML declaration line is this the first line in the file(s)? If so, you can remove the first line like this:
sed -i "1d" <filename>
The -i edits the file in place so will overwrite your original, while the "1d" command simply deletes a line.
However, if it's not the first line, or appears multiple times, then you can use this:
sed -i '/\?xml/d' <filename>
Again, it's editing in place and using the d command to delete, but this time it's deleting based on the regular expression. You might want to expand the regex a bit so that it's more targeted, but the principle is there.
You say in the comments that it's just part of a line that you want to remove, so in that case:
sed -i "s/<?xml .*?\?>//" <filename>
Summed up as "replace everything between "" with nothing (effectively delete it).
Use double quotes for the outer quotes to avoid the escape issue:
sed "s/<?xml version='1.0' encoding='UTF-8'?>//g" myFile > myFile1
If you search for "string" in a directory, it should give you the top 3 and bottom 3 occurrences of the string in all the files, and output that to an out file.
I am using:
grep string path-to-file | head -3 > out.log
grep string path-to-file | tail -3 >> out.log
sed '/<?xml version='1.0' encoding='UTF-8'?>/d' myfile .
Apart from the issue with the quotes, you might consider using grep -v instead of sed:
grep -v "<?xml version='1.0' encoding='UTF-8'?>" myFile > myFile1
But if you know that the line you don't want is always the first line in the file, the following is even easier:
tail -n +2 myFile > myFile1
Please find the below script.
sed 's/\<\?xml version\=\'1\.0\' encoding\=\'UTF\-8\'\?\>//g' myfile > myfile_new
Idea is to comment the special characters.
sed -e 's/<[^>]*>//g' myfile should work

How to remove blank lines from a Unix file

I need to remove all the blank lines from an input file and write into an output file. Here is my data as below.
11216,33,1032747,64310,1,0,0,1.878,0,0,0,1,1,1.087,5,1,1,18-JAN-13,000603221321
11216,33,1033196,31300,1,0,0,1.5391,0,0,0,1,1,1.054,5,1,1,18-JAN-13,059762153003
11216,33,1033246,31300,1,0,0,1.5391,0,0,0,1,1,1.054,5,1,1,18-JAN-13,000603211032
11216,33,1033280,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,055111034001
11216,33,1033287,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,000378689701
11216,33,1033358,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,000093737301
11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802041926
11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802041954
11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802049326
11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802049383
11216,33,1036985,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000093415580
11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781202001
11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781261305
11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781603955
11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781615746
sed -i '/^$/d' foo
This tells sed to delete every line matching the regex ^$ i.e. every empty line. The -i flag edits the file in-place, if your sed doesn't support that you can write the output to a temporary file and replace the original:
sed '/^$/d' foo > foo.tmp
mv foo.tmp foo
If you also want to remove lines consisting only of whitespace (not just empty lines) then use:
sed -i '/^[[:space:]]*$/d' foo
Edit: also remove whitespace at the end of lines, because apparently you've decided you need that too:
sed -i '/^[[:space:]]*$/d;s/[[:space:]]*$//' foo
awk 'NF' filename
awk 'NF > 0' filename
sed -i '/^$/d' filename
awk '!/^$/' filename
awk '/./' filename
The NF also removes lines containing only blanks or tabs, the regex /^$/ does not.
Use grep to match any line that has nothing between the start anchor (^) and the end anchor ($):
grep -v '^$' infile.txt > outfile.txt
If you want to remove lines with only whitespace, you can still use grep. I am using Perl regular expressions in this example, but here are other ways:
grep -P -v '^\s*$' infile.txt > outfile.txt
or, without Perl regular expressions:
grep -v '^[[:space:]]*$' infile.txt > outfile.txt
sed -e '/^ *$/d' input > output
Deletes all lines which consist only of blanks (or is completely empty). You can change the blank to [ \t] where the \t is a representation for tab. Whether your shell or your sed will do the expansion varies, but you can probably type the tab character directly. And if you're using GNU or BSD sed, you can do the edit in-place, if that's what you want, with the -i option.
If I execute the above command still I have blank lines in my output file. What could be the reason?
There could be several reasons. It might be that you don't have blank lines but you have lots of spaces at the end of a line so it looks like you have blank lines when you cat the file to the screen. If that's the problem, then:
sed -e 's/ *$//' -e '/^ *$/d' input > output
The new regex removes repeated blanks at the end of the line; see previous discussion for blanks or tabs.
Another possibility is that your data file came from Windows and has CRLF line endings. Unix sees the carriage return at the end of the line; it isn't a blank, so the line is not removed. There are multiple ways to deal with that. A reliable one is tr to delete (-d) character code octal 15, aka control-M or \r or carriage return:
tr -d '\015' < input | sed -e 's/ *$//' -e '/^ *$/d' > output
If neither of those works, then you need to show a hex dump or octal dump (od -c) of the first two lines of the file, so we can see what we're up against:
head -n 2 input | od -c
Judging from the comments that sed -i does not work for you, you are not working on Linux or Mac OS X or BSD — which platform are you working on? (AIX, Solaris, HP-UX spring to mind as relatively plausible possibilities, but there are plenty of other less plausible ones too.)
You can try the POSIX named character classes such as sed -e '/^[[:space:]]*$/d'; it will probably work, but is not guaranteed. You can try it with:
echo "Hello World" | sed 's/[[:space:]][[:space:]]*/ /'
If it works, there'll be three spaces between the 'Hello' and the 'World'. If not, you'll probably get an error from sed. That might save you grief over getting tabs typed on the command line.
grep . file
grep looks at your file line-by-line; the dot . matches anything except a newline character. The output from grep is therefore all the lines that consist of something other than a single newline.
with awk
awk 'NF > 0' filename
To be thorough and remove lines even if they include spaces or tabs something like this in perl will do it:
cat file.txt | perl -lane "print if /\S/"
Of course there are the awk and sed equivalents. Best not to assume the lines are totally blank as ^$ would do.
Cheers
You can sed's -i option to edit in-place without using temporary file:
sed -i '/^$/d' file

Replace \n with \r\n in Unix file

I'm trying to do the opposite of this question, replacing Unix line endings with Windows line endings, so that I can use SQL Server bcp over samba to import the file. I have sed installed but not dos2unix. I tried reversing the examples but to no avail.
Here's the command I'm using.
sed -e 's/\n/\r\n/g' myfile
I executed this and then ran od -c myfile, expecting to see \r\n where there used to be \n. But there all still \n. (Or at least they appear to be. The output of od overflows my screen buffer, so I don't get to see the beginning of the file).
I haven't been able to figure out what I'm doing wrong. Any suggestions?
When faced with this, I use a simple perl one-liner:
perl -pi -e 's/\n/\r\n/' filename
because sed behavior varies, and I know this works.
What is the problem with getting dos2unix onto the machine?
What is the platform you are working with?
Do you have GNU sed or regular non-GNU sed?
On Solaris, /usr/bin/sed requires:
sed 's/$/^M/'
where I entered the '^M' by typing controlV controlM. The '$' matches at the end of the line, and replaces the end of line with the control-M. You can script that, too.
Mechanisms expecting sed to expand '\r' or '\\r' to control-M are going to be platform-specific, at best.
You don't need the -e option.
$ matches the endline character. This sed command will insert a \r character before the end of line:
sed 's/$/\r/' myfile
Just adding a \r (aka ^M, see Jonathan Leffler's answer) in front of \n is not safe because the file might have mixed mode EOL, so then you risk ending up with some lines becomming \r\r\n. The safe thing to do is first remove all '\r' characters, and then insert (a single) \r before \n.
#!/bin/sh
sed 's/^M//g' ${1+"$#"} | sed 's/$/^M/'
Updated to use ^M.
sed 's/\([^^M]\)$/\0^M/' your_file
This makes sure you only insert a \r when there is no \r before \n. This worked for me.
Try using:
echo " this is output" > input
sed 's/$/\r/g' input |od -c
Maybe if you try it this way
cat myfile | sed 's/\n/\r\n/g' > myfile.win
will work, from my understanding your just making the replacements to the console output, you need to redirect output to a file, in this case myfile.win, then you could just rename it to whatever you want. The whole script would be (running inside a directory full of this kind of files):
#!/bin/bash
for file in $(find . -type f -name '*')
do
cat $file | sed 's/\n/\r\n/g' > $file.new
mv -f $file.new $file
done

Resources