creating a blank line after some specific line using bash / linux - linux

I need to add an additional blank line after the line 45 using sed
for example:
44 some text one
45 some text two
46 some text three
47 some text four
result:
44 some text one
45 some text two
46
47 some text three
48 some text four
I've tried to use
sed '45G' myfile.txt
but not seems to be working, it does prints content of the file on the screen but do not adds any space after the line 45
Using CentOS 7 minimal

You can do:
sed $'45 a \n' file.txt
$'' initiates C-style quoting, might be needed in some sed while using \n
45 a \n appends a newline (\n) after (a) the 45-th line

sed is for simple substitutions on individual lines, that is all. For anything else just use awk:
awk '{print} NR==45{print ""}' file
That will work with any awk on any UNIX box.

Related

Why is translate working and not sed for line feed

I would like to replace linefeed by something else like #
I have tried sed but \n doesn't work and \x0a as well
I got file z1
cat z1|hd
00000000 30 0a 61 0a 0a 31 0a 62 0a 0a 32 0a 63 0a |0.a..1.b..2.c.|
and if i try
cat z1|sed $'s/\x30//g'
everything is fine
But it doesn't work for line feed in sed, just an error message
cat z1|sed $'s/\x0a//g'
If i try
cat z1| tr "\n" "#"|hd
everything is fine for linefeed
Why is sed not working for linefeed ?
sed will not match literal newline, because commands in sed are delimetered by a newline. So sed, when parses the command, sees a newline and assumes it is the end of this command. And then sed errors with a syntax error, because s/ is an invalid command, the s needs three delimeter characters, / here. More specifically, posix sed documentation explicitly forbids embedding literal newline in BRE inside s/BRE/replacement/flags command: A literal <newline> shall not be used in the BRE of a context address or in the substitute function.
Outside from that, sed parses the input line after line, but ignores the newline from input and automatically appends a newline when printing. So even if you did s/\n/#/ it wouldn't do anything, because there is no newline in the input. You can: append all the lines into hold space, then switch hold space with pattern space and then substitute newlines. This is the solution presented by #potong.
This might work for you (GNU sed):
sed '1h;1!H;$!d;x;y/\n/#/' file
This slurps the file into memory, then translate \n's to #'s
Alternative:
sed -z 'y/\n/#/' file
There are sed versions which accept \n or hex character codes but this is not portable. If you can't use tr (why not?) then maybe explore Perl, which of course is not standard at all, but available practically everywhere; and because there is only one implementation, it will work everywhere Perl is available.
perl -pe 'y/\n/#/' z1
Also note the absence of a useless cat.

Swap columns of a file - Linux (exact position, not word)

I would like to know how to swap columns (the exact character) of a file with Linux (using cut, awk, sed or whatever you can help me with).
I have seen how to swap a whole expression (using delimiters) and whole words.
Example:
128934
38 2008
Swapping column 3 with 5:
123984
3802 08
Another way to ask this, would be swap the 3rd char of each row with the 5th.
You can do it with gawk, mawk, nawk and busybox awk with this non-posix complient example:
awk -v FS='' -v OFS='' '{ t=$3; $3=$5; $5=t } 1' infile
Output:
123984
3802 08
A bit unwieldy, with sed:
$ sed -E 's/^(..)(.)(.)(.)/\1\4\3\2/' infile
123984
3802 08
This captures the first five characters of each line in four groups and then rearranges them. -E is just there for convenience; without it, we have to escape the parentheses as in \(.\).

Delete everything after a certain character on each word using sed

I want to create a script using sed to achieve the following:
This:
22/0,01 1/1,05 11/0,01 35/6,04 6/0,03 3/0,04
To:
22 1 11 35 6 3
I want to remove everything after "/" on each word.
Just remove everything from / up to a space:
$ sed 's#/[^ ]*##g' file
22 1 11 35 6 3
Note I am using # as delimiter to avoid having to escape the /.
if the "everything after the / consists only of known characters, then this is rather easy:
sed -e 's|/[0-9,]*||g'

echo command in script wiht input from excel.txt file

First: Many thanks for taking the effort to read and answer this post
What I want to do:
I would like to read lines from a txt file (each line may contain 1 or 2 words) and then echo a text saying:
curl "text.word1+word2"
How I do it:
while read line
do
kw=( $line )
echo 'curl "text.'${kw[0]}+${kw[1]}'"'
done
Remark: there are additional if command in my file i did not post here
Problem
While this works fine when I execute it in the terminal and enter a line in the terminal, it does not product the desired result when I use a txt file as input
The text file is an excel file where I have text in the first column. I save the excel file as "Windows formatted text (.txt) and can open the resulting name.txt file in an editor (seeing a "normal" text file)
when I use in the terminal now
./myscript.command < name.txt
the result will be
"url "text.word1+word2
instead of
curl "text.word1+word2"
Any ideas how to solve this?
Many thanks!
${kw[1]} has a carriage return character at the end of it, what you're seeing is:
curl "text.word1+word2
"
with the second line overwriting the first.
You can confirm this by doing a hex dump on the file, such as with:
od -xcb name.txt
and looking for those pesky \r characters.
The following transcript shows this in detail:
pax> od -xcb name.txt
0000000 6150 2078 6944 6261 6f6c 0a0d
P a x D i a b l o \r \n
120 141 170 040 104 151 141 142 154 157 015 012
0000014
pax> cat name.sh
#!/bin/bash
while read line ; do
kw=( $line )
echo 'curl "text.'${kw[0]}+${kw[1]}'"'
done <name.txt
pax> ./name.sh
"url "text.Pax+Diablo
As to how you get rid of the carriage return, there are numerous solutions, some of which are:
dos2unix;
tr -d '\r'; or
sed 's/\r$//'.
Your weapon of choice depends on what tools you have available to you, dos2unix is probably the easiest if you have it to hand.
DOS uses CRLF for new line(each line ends with two characters, CR then LF). Unix uses LF only (each line ends with an \n character).
To convert dos file format into unix file format use
$ dos2unix filename
It will solve your problem.
This code works fine:
while read line
do
kw=( $line )
echo 'curl "text.'${kw[0]}+${kw[1]}'"'
done < $1
And generates:
./text_line.sh text.txt
curl "text.aaa+aaa"
curl "text.bbb+bbb"
curl "text.ccc+"
curl "text.ddd+ddd"

How to remove words from a file in UNIX?

first file of information page
name/joe/salary1 50 10 2
name/don/miles2
20 4 3
name/sam/lb3 0 200 50
can some one please tell me how can I remove all the words in the above file, so my output will looks as follows
50 10 2
20 4 3
0 200 50
Use awk instead. The following code says to go through each field, check if its an integer. If it is, print them out. No need complicated regex.
$ awk '{for(i=1;i<=NF;i++) if($i+0==$i) {printf $i" "} print ""}' file
50 10 2
20 4 3
0 200 50
sed -e "s/[a-zA-Z/]/ /g" file
will do it, though I like codaddict's way more if you want to preserver number and whitespace. This way strips out all letters and the '/' symbol, replacing them all with space.
If you want to modify the file in place, pass the -i switch. This command will output what the file would look like.
Looks like you want to preserve only the digits and the space. If yes, you can do:
sed 's/[^0-9 ]//g' inputFile
EDIT: Change in requirements, if a digit is found with a letter, it should be treated as part of the word.
This Perl script does it:
perl -ne 's/(?:\d*[a-z\/]+\d*)*//g;print' input
If your file has this structure, I suggest first to filter out the first line, then remove all characters from beginning of line up to the first space:
sed -ni '2,$s/^[^ ]*//p' file
Remove everything on each line until first space character (also removes leading spaces):
sed 's/\S*\s*//' file

Resources