Is it possible to tell Ruby in Windows to use only \n instead of r\n?
I'm having an issue where a file is being saved with \r\n and it is causing it to not function properly. Is there a setting somewhere I can change to fix this?
The simple attack:
File.open("foo.txt", "w") do |fd|
fd.write "this\nis\a\test\n"
end
And when I open this in hexedit:
00000000 74 68 69 73 0A 69 73 0A 61 0A 74 65 73 74 0A
^^ ^^ ^^ ^^
\n \n \n \n
Related
I'm trying to run my shell script on Linux (Ubuntu).
It's running correctly on MacOS, but on Ubuntu it doesn't.
#!/usr/bin/env bash
while true
do
node Client/request -t 10.9.2.4 -p 4400 --flood
done
Ubuntu output this error for running: sh myScript.sh:
Syntax error: end of file unexpected (expecting "do")
Why is there any difference between them, since both of them are running by Bash? How can I avoid future errors caused by their differences?
I tried cat yourscript.sh | tr -d '\r' >> yournewscript.sh as related question was suggested to do, and also while [ true ].
The command hexdump -C util/runner.sh result is:
00000000 23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 62 |#!/usr/bin/env b|
00000010 61 73 68 0d 0a 0d 0a 77 68 69 6c 65 20 5b 20 74 |ash....while [ t|
00000020 72 75 65 20 5d 0d 0a 64 6f 0d 0a 20 20 20 6e 6f |rue ]..do.. no|
00000030 64 65 20 43 6c 69 65 6e 74 2f 72 65 71 75 65 73 |de Client/reques|
00000040 74 20 2d 74 20 31 39 32 2e 31 36 38 2e 30 2e 34 |t -t 192.168.0.4|
00000050 31 20 2d 70 20 34 34 30 30 20 2d 2d 66 6c 6f 6f |1 -p 4400 --floo|
00000060 64 0d 0a 64 6f 6e 65 0d 0a |d..done..|
00000069
The shebang #! line at the top of your file tells that this is a bash script. But then you run your script with sh myScript.sh, therefore using the sh shell.
The sh shell is not the same as the bash shell in Ubuntu, as explained here.
To avoid this problem in the future, you should call shell scripts using the shebang line. And also make sure to prefer bash over sh, because the bash shell is more convenient and standardized (IMHO). In order for the script to be directly callable, you have to set the executable flag, like this:
chmod +x yournewscript.sh
This has to be done only once (it's not necessary to do this on every call.)
Then you can just call the script directly:
./yournewscript.sh
and it will be interpreted by whatever command is present in the first line of the script.
A certain downstream sink (that I don't control), being fed w/ html, ecstatically trims down all spaces & newlines into 1 space. Thus I need to 'escape' such chars inside all <pre> tags.
I've managed to 'protect' newlines by replacing them w/ <br>, but the spaces issue stupefies me:
require 'nokogiri'
doc = Nokogiri::HTML.fragment "<pre><code> 1\n\n 2</code></pre>"
doc.css('pre').each do |node|
text = node.to_s.gsub(/\n/, '<br>').gsub(/\s/) { ' ' }
node.replace Nokogiri::HTML.fragment text
end
puts doc
still yields in:
<pre><code> 1<br><br> 2</code></pre>
(instead of expected <pre><code> 1<br><br> 2</code></pre>)
i.e., Nokogiri re-encodes to spaces again!
Now, here's what also interesting: those are not actual 'spaces', but (I gather) UTF8 non breaking space chars:
$ ruby 1.rb | hexdump -C
00000000 3c 70 72 65 3e 3c 63 6f 64 65 3e c2 a0 c2 a0 31 |<pre><code>....1|
00000010 3c 62 72 3e 3c 62 72 3e c2 a0 c2 a0 32 3c 2f 63 |<br><br>....2</c|
00000020 6f 64 65 3e 3c 2f 70 72 65 3e 0a |ode></pre>.|
0000002b
notice c2 a0 c2 a0 31 (<nbsp><nbsp>1) instead of more common 20 20 31.
I don't think its prudent to blindly enforce non-UTF8 encoding on my output, so playing w/ various encodings isn't an option.
I'm trying to do a simple tcsh script to look for a folder, then navigate to it if it exists. The statement evaluates properly, but if it evaluates false, I get an error "then: then/endif not found". If it evaluates true, no problem. Where am I going wrong?
#!/bin/tcsh
set icmanagedir = ""
set workspace = `find -maxdepth 1 -name "*$user*" | sort -r | head -n1`
if ($icmanagedir != "" && $workspace != "") then
setenv WORKSPACE_DIR `readlink -f $workspace`
echo "Navigating to workspace" $WORKSPACE_DIR
cd $WORKSPACE_DIR
endif
($icmanagedir is initialized elswehere, but I get the error regardless of which variable is empty)
The problem is that tcsh needs to have every line end in a newline, including the last line; it uses the newline as the "line termination character", and if it's missing it errors out.
You can use a hex editor/viewer to check if the file ends with a newline:
$ hexdump -C x.tcsh i:arch:21:49
00000000 69 66 20 28 22 78 22 20 3d 20 22 78 22 29 20 74 |if ("x" = "x") t|
00000010 68 65 6e 0a 09 65 63 68 6f 20 78 0a 65 6e 64 69 |hen..echo x.endi|
00000020 66 |f|
Here the last character if f (0x66), not a newline. A correct file has 0x0a as the last character (represented by a .):
$ hexdump -C x.tcsh
00000000 69 66 20 28 22 78 22 20 3d 20 22 78 22 29 20 74 |if ("x" = "x") t|
00000010 68 65 6e 0a 09 65 63 68 6f 20 78 0a 65 6e 64 69 |hen..echo x.endi|
00000020 66 0a |f.|
Ending the last line in a file with a newline is a common UNIX idiom, and some shell tools expect this. See What's the point in adding a new line to the end of a file? for some more info on this.
Most UNIX editors (such as Vim, Nano, Emacs, etc.) should do this by default, but some editors or IDEs don't do this by default, but almost all editors have a setting through which this can be enabled.
The best solution is to enable this setting in your editor. If you can't do this then adding a blank line at the end also solves your problem.
This question already has answers here:
How can I output null-terminated strings in Awk?
(4 answers)
Closed 7 years ago.
I have a function which outputs some file paths, I need these paths are separated by NUL charachter instead of new line \n character. I tried following code:
function myfunc
{
declare -a DUPS
# some commands to fill DUPS with appropriate file/folder paths
( for i in "${DUPS[#]}"; do echo "$i"; done )|sort|uniq|awk 'BEGIN{ORS="\x00";} {print substr($0, index($0, $2))}'
}
But if I pipe its output to hexdump or hd, no NUL character is diplayed. It seems that NUL character is not included in the awk output:
myfunc | hd
Will print:
00000000 2f 70 61 74 68 2f 6e 75 6d 62 65 72 2f 6f 6e 65 |/path/number/one|
00000010 2f 2f 70 61 74 68 2f 6e 75 6d 62 65 72 2f 74 77 |//path/number/tw|
00000020 6f 2f 2f 70 61 74 68 2f 6e 75 6d 62 65 72 2f 74 |o//path/number/t|
00000030 68 72 65 65 2f |hree/|
00000035
My awk version is:
~$ awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
compiled limits:
max NF 32767
sprintf buffer 2040
Also any solution with other commands such as sed is acceptable for me.
NOTE: My question is not duplicate of enter link description here, because it asks for a solution that works on different machines with different awks. But I just need a solution that works on my own machine, so I could use any version of awk that could be installed on Ubuntu 14.04.
Gnu Awk v4.0.1 works just fine with your original program, but all the other awks I have kicking around (mawk, original-awk and busybox awk) produce the same NUL-free output as you seem to be experiencing. It appears that with those awks, using either print or printf to print a string with embedded NULs causes the NUL to be treated as a string terminator.
However, mawk and original-awk will output a real NUL if you use printf "%s",0;. So if you are using one of those, you could set ORS to the empty string and add {printf "%s", 0;} to the end of your awk program. (You'd need other more invasive modifications if your awk program uses next).
I don't know any way to convince busybox awk to print a NUL byte, so if that is what you are using you might want to consider choosing a real awk.
I am using sed on Windows (the GNU port).
I execute:
$> sed "s/$/./" < /data.txt
And get:
.ne
.wo
.hree
But expect.
one.
two.
three.
The following works though I don't think it should. The way I read it is "replace the last character of the line with a period." I'm afraid it won't work consistently when used elsewhere. The intent isn't to replace the last character with a period but to append a period.
$> sed "s/.$/./" < /data.txt
I am not sure if the file encoding or something specific to windows is causing the issues I'm having or if it's just lack of experience with sed. Ideas?
hexdump -C sheds some light:
$ sed 's/$/./' < t.dos | hexdump -C
00000000 6f 6e 65 0d 2e 0a 74 77 6f 0d 2e 0a 74 68 72 65 |one...two...thre|
00000010 65 0d 2e 0a |e...|
00000014
There, 2e is the dot, the 0d before it is carriage return aka \r, and after that is the newline aka \n. In other words, sed treats \r as the end of the line instead of \r\n together, and thus \r is still part of the line, so it puts the dot after it, then adds back the newline as usual.
I think this does what you want, but it's not exactly pretty:
$ sed 's/.$/.\r/' < t.dos | hexdump -C
00000000 6f 6e 65 2e 0d 0a 74 77 6f 2e 0d 0a 74 68 72 65 |one...two...thre|
00000010 65 2e 0d 0a |e...|
00000014
The above is not so good, because it will only work if the input is in dos format, otherwise it will break the file. A better solution might be to first strip any \r and add them back manually later, like this:
$ tr -d '\r' < t.dos | sed -e 's/$/.\r/' | hexdump -C
00000000 6f 6e 65 2e 0d 0a 74 77 6f 2e 0d 0a 74 68 72 65 |one...two...thre|
00000010 65 2e 0d 0a |e...|
00000014