Reputation: 101
Gawk manual says about sprintf: "Return (without printing) the string that printf would have printed out..."
Here is the printf output:
awk '{ printf "%s", $0 }' <<< 'line1
line2'
line1line2%
However, sprintf seems to preserve newlines:
awk '{ my_var=sprintf("%s", $0); print my_var }' <<< 'line1
line2'
line1
line2
(The same with BSD and GNU awk.)
Why is it so?
How do I put in a variable the newline-stripped content this way, without using RS/ORS/sub?
Upvotes: 0
Views: 705
Reputation: 2801
if u just wanna concat it all without \n
:
% jot 30 | mawk _^_ ORS=
123456789101112131415161718192021222324252627282930% # "...%" = no trailing \n
To add back 1 more trailing newline, it's easier via the pipe :
jot 30 | gawk // ORS= | nawk $$
123456789101112131415161718192021222324252627282930
another way to add back the trailing new line while stripping all input inewlines would be like :
mawk2 ++NF OFS= RS= FS='\412'
123456789101112131415161718192021222324252627282930
if u wanna convert vertical input to horizontal :
nawk NF=NF FS='\n' RS=
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
horizontal without trailing newline :
gawk 8 ORS=' '
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30%
Upvotes: 0
Reputation: 203512
Regarding sprintf seems to preserve newlines
- no, awk consumes the newline when it reads the record. In:
awk '{ my_var=sprintf("%s", $0); print my_var }' <<< 'line1
line2'
$0
never contains a newline and so the output of that sprintf
doesn't contain a newline. The print
command adds a newline when outputting my_var
. If you did:
print "<" my_var ">"
then you'd see that my_var
doesn't contain a newline, the newline appears after the >
, not before it.
I'm saying newline
above but it's really whatever value RS
has on input and ORS
on output, they're both just newline by default.
Regarding How do I put in a variable the newline-stripped content this way
- that's already what it contains. If you want my_var
to then be output without a newline being appended then do either this:
printf "%s", my_var
or this:
ORS=""; ...; print my_var
Upvotes: 2
Reputation: 37404
If you feed awk (2 records of) data with a newline in the middle, ie.:
<<<'line1
line2'
awk is going to process the input record by record (notice the NR
in code, don't mind the ()
after printf
:
$ awk '{ printf("%s %s", NR, $0) }' <<< 'line1
line2'
1 line12 line2$
or
$ awk '{ print sprintf("%s %s", NR, $0) }' <<< 'line1
line2'
1 line1
2 line2
$
In the former printf
didn't produce newline after either of the records, in the latter print
did.
If you want to preserve the newline (between records), read the whole data in at once without processing the newlines (well, this does involve using RS
):
$ awk -v RS="^$" '{ printf("%s %s", NR, $0) }' <<< 'line1
line2'
1 line1
line2
$
If you are unable to use the RS
, you need to parse the input yourself. Sample data, cat file
:
line1
line2 \\
line3 \
line4
line5
\
marks to attach 2 records, \\
is a backslash:
$ awk '{
if(/[^\\]\\$/) { # if ends in one \
b=b substr($0,1,length($0)-1) ORS # append to buffer b
next # on to next record
}
$0=b $0 # prepend buffer to record
gsub(/\\\\/,"\\") # \\s to \s
print sprintf("%s %s", ++c, $0) # output, NR replace with c
b="" # empty the buffer
}' file
Output:
1 line1
2 line2 \
3 line3
line4
4 line5
Upvotes: 1
Reputation: 84561
If You Want To Remove the '\n'
If you want to strip the newline, then sed
makes that easy:
$ sed '/[\]/{N;s/\n//}' <<< 'line1 \
line2'
line1 \line2
Or you can use awk
as:
$ awk '/\\$/ {line = line $0; next} { print line $0; line = ""}' <<< 'line1 \
line2'
line1 \line2
Where you simply concatenate lines ending in \
and then output all of the concatenated lines along with the current line for the first line not ending in '\'
and reset the variable you are accumulating the lines in (line
above).
You can handle trailing whitespace between the '\'
and end of line by adding /\\[[:blank:]]*$/
to your Regex.
Let me know if I missed your intent and I'm happy to help further.
Upvotes: 2
Reputation: 36450
How do I put in a variable the newline-stripped content this way, without using RS/ORS/sub?
Use sprintf
return value(s) as argument(s) to printf
, consider following example, let file.txt
content be
12.12 14.14 16.16
then
awk '{x=sprintf("%d",$1);y=sprintf("%d",$2);z=sprintf("%d",$3)}END{printf "%s%s%s",x,y,z}' file.txt
gives output
121416
(without trailing newline)
(tested in GNU Awk 5.0.1)
Upvotes: 1