How to write multilines to a file with fish? - cat

In bash, I can do:
cat >a.txt <<EOF
line 1111
line 2222
EOF
But this is invalid syntax when using in fish. What's the correct way to do it?

You can use echo and a multiline string (adapted from this thread in the fish issue tracker)
echo >a.txt "\
line 1111
line 2222"

FWIW in the console/terminal I have always used:
cat > a.txt
line 1111
line 2222
Ctrl+D
It worked both in Bash and Fish.

Related

Bash: redirect `cat` to file without newline

I'm sure this question has been answered somewhere, but while searching for it, I can't find my exact scenario. I have two files that I am concatenating into a single file, but I am also adding user input between the two files. The problem is that a newline is being inserted after the first file, the rest of it works as desired.
touch newFile
cat file1 > newFile
echo -n $userInput >> newFile
cat file2 >> newFile
How do I prevent or remove the newline when file1 is added to newFile? If I cat file1 there seems to be a newline added by cat but everything I see about cat says it doesn't do that. If I vim file1 there's not a blank line at the end of the file that would indicate the newline is a part of the file, so either cat is actually adding a newline, or the redirect > is doing it, or echo adds a newline at the beginning of its output, none of which would be desirable in this situation. One solution I saw was to use
cat file1 | tr -d '\n'
but that discards all the newlines in the file, also not desirable. So, to repeat my question:
How do I cat file1 into the new file and add user input without adding the newline between them?
(cat is not a requirement, but I am not familiar with printf, so if that's the solution then please elaborate on its use).
With these inputs:
userInput="Test Test Test"
echo "Line 1
Line 2
Line 3" >file1
echo "Line 4
Line 5
Line 6" >file2
I would do:
printf "%s%s%s" "$(cat file1)" "$userInput" "$(cat file2)" >newfile
The creation of >newfile is equivalent to touch and adding content in your first step. A bit easier to see intent with this.
I get:
$ cat newfile
Line 1
Line 2
Line 3Test Test TestLine 4
Line 5
Line 6
Like all other Unix tools, Vim considers \n a line terminator and not a line separator.
This means that a linefeed after the last piece of text will be considered part of the last line, and will not show an additional blank line.
If there is no trailing linefeed, Vim will instead show [noeol] in the status bar when the file is loaded:
foo
~
~
~
~
~
"file" [noeol] 1L, 3C 1,1 All
^---- Here
So no, the linefeed is definitely part of your file and not being added by bash in any way.
If you want to strip all trailing linefeeds, you can do this as a side effect of command expansion:
printf '%s' "$(<file1)" >> newfile
touch newFile
echo -n "$(cat file1)" > newFile
echo -n $userInput >> newFile
cat file2 >> newFile
That did the trick.

what would this line of command do? grep ^..[l-z]$ hello.txt

I am wondering what would this line of command do:
grep ^..[l-z]$ hello.txt
I know grep but I don't know what is this part " ^..[I-z]$ " do?
I am using Linux Ubuntu.
Your command will search only for the line which contains 3 Alphanumeric characters from start to last in which the last character belongs to l to z.
see below example -
cat hello.txt
hello vipin
..l
1ll
1la
abl
..l
#.z
1.a
..l..
..vipin
grep ^..[l-z]$ hello.txt
..l
1ll
abl
#.z
it searches all lines that are build of exactly 3 letters where the last is one of l through z

How do I append a line to the beginning of a very large file in Linux?

I have a large text file of ~45 GB, and need to append a line both at the beginning and at the end of the file. What is the quickest way to accomplish this? I don't have access to any big data framework such as Hadoop, etc.
In addition, if I have to also do a string replace in this large file, is there a similar efficient way?
I tried with echo command and it really is taking ages.
You can use this sed to add a line in the beginning:
sed -i '1s/^/your heading line\n/' file
And to the end:
echo "my new line" >> file
Test
$ cat a
hello
bye
$ sed -i '1s/^/new line sample\n/' a
$ cat a
new line sample
hello
bye
$ echo "my new line" >> a
$ cat a
new line sample
hello
bye
my new line
Using sed, you could say:
sed -e '1ifoo' -e '$abar'
and this would insert foo at the top of the file and bar at the end of the file.
$ seq 5 | sed -e '1ifoo' -e '$abar'
foo
1
2
3
4
5
bar

Getting an error with sed expression

I am using this command in a shell script
lnum=5
str="Hello foo"
filename="/path/fiename"
sed -i "$lnum i $str" $filename
Getting the following error
sed: -e expression #1, char 3: : doesn't want any addresses
I had used this command before for other script it worked fine, the only change i made this time is file-name has a path to the file, but I tried it with just giving file-name and not the path by getting into the path and executing the script but still it doesn't work
I am unable to resolve it can anybody help
If you are using OSX , BSD (and AIX) versions of sed, the backup extension for the -i in place editing flag is not optional.
GNU sed differs on this I believe, so the script may work on Linux.
This is a bit of a pain for portability - but it gets worse with "in-place" editing when BSD derived sed is used. This version of sed is arguably more "standard" in some ways (as in: "lowest common denominator across POSIX systems") but this behaviour seems like a bug:
sed: 1: "5 i hello foo": command i expects \ followed by text
Here is how I made your script work on several BSD flavors:
lnum="5"
str="Hello foo"
filename="sed-mess.txt"
sed -i "" "$lnum i\^M
$str" $filename
I had to enter a literal line end character with Ctrl-v [Return] to get the i command to work since \ is required and has to have nothing following it. Not sure how GNU sed would handle this.
Can you use perl ? ;-)
The old farts use ed for this type of problem:
cat /tmp/sample
#!/bin/ksh
lnum=5
str="Hello bar"
filename="/tmp/foo"
ed - $filename <<EOF
$lnum
i
$str
.
w
q
EOF
cat /tmp/foo
line
line
line
line
line
line
line
line
line
wc /tmp/foo
9 9 45 /tmp/foo
/tmp/sample
line
wc /tmp/foo
10 11 55 /tmp/foo
cat /tmp/foo
line
line
line
line
Hello bar
line
line
line
line
line
i is "insert" before while a is "append" after. I don't know what the sed i command does exactly but I would expect it would be the same as i
Hope this helps

Simple command for showing comments on shell script

Suppose you have the following script:
# My comment line 1
# My comment line 2
# My comment line 3
echo "My script"
cd $MY_PATH
./anotherScript.ksh
Is there any command to show:
# My comment line 1
# My comment line 2
# My comment line 3
Alternatively, I could write a script to detect the first block of comments.
Thanks
Try this:
grep '^\#.*$' myscript.sh
You could cat script.sh | grep ^\# to only show those lines.
This will output your file to the grep command which will print each line with a "#"
echo "My script" | grep "#"
EDIT I'M DUMB
all you need to do is grep '#' file if I'm understanding correctly this time.

Resources