Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-line variables remove new line character - Fish

Tags:

shell

fish

When I set any multiline text as a variable in fish, it removes the new line characters and replaces them with space, how can I stop it from doing that? Minimal complete example:

~ ) set lines (cat .lorem); set start 2; set end 4;
~ ) cat .lorem 
once upon a midnight dreary while i pondered weak and weary
over many a quaint and curious volume of forgotten lore
while i nodded nearly napping suddenly there came a tapping
as of some one gently rapping rapping at my chamber door
tis some visiter i muttered tapping at my chamber door
~ ) cat .lorem | sed -ne $start\,{$end}p\;{$end}q  # Should print lines 2..4
over many a quaint and curious volume of forgotten lore
while i nodded nearly napping suddenly there came a tapping
as of some one gently rapping rapping at my chamber door
~ ) echo $lines
once upon a midnight dreary while i pondered weak and weary over many a quaint and curious volume of forgotten lore while i nodded nearly napping     suddenly there came a tapping as of some one gently rapping rapping at my chamber door tis some visiter i muttered tapping at my chamber door
like image 517
user14492 Avatar asked Dec 08 '15 21:12

user14492


People also ask

How do you set a fish's variable?

Unlike other shells, fish has no dedicated VARIABLE=VALUE syntax for setting variables. Instead it has an ordinary command: set , which takes a variable name, and then its value.

How do I change my fish prompt?

Prompt Tab The "prompt" tab displays the contents of the current fish shell prompt. It allows selection from 17 predefined prompts. To change the prompt, select one and press "Prompt Set!". DANGER: This overwrites ~/.

How do you set the path on a fish shell?

It does this by adding the components either to $fish_user_paths or directly to $PATH (if the --path switch is given). It is (by default) safe to use fish_add_path in config. fish, or it can be used once, interactively, and the paths will stay in future because of universal variables.

What is config fish?

Description. fish_config is used to configure fish. Without arguments or with the browse command it starts the web-based configuration interface. The web interface allows you to view your functions, variables and history, and to make changes to your prompt and color configuration.


2 Answers

fish splits command substitutions on newlines. This means that $lines is a list. You can read more about lists here.

When you pass a list to a command, each entry in the list becomes a separate argument. echo space-separates its arguments. That explains the behavior you're seeing.

Note that other shells do the same thing here. For example, in bash:

lines=$(cat .lorem)
echo $lines

If you want to prevent the splitting, you can temporarily set IFS to empty:

begin
   set -l IFS
   set lines (cat .lorem)
end
echo $lines

now $lines will contain newlines.

As faho says, read can also be used and is a little shorter:

read -z lines < ~/.lorem
echo $lines

but consider whether splitting on newlines might actually be what you want. As faho hinted, your sed script can be replaced with array slices:

set lines (cat .lorem)
echo $lines[2..4] # prints lines 2 through 4
like image 66
ridiculous_fish Avatar answered Oct 13 '22 21:10

ridiculous_fish


Pipe it to string split0.

set lines (echo -e 'hi\nthere')
set -S lines
# $lines: set in global scope, unexported, with 2 elements
# $lines[1]: length=2 value=|hi|
# $lines[2]: length=5 value=|there|

set lines (echo -e 'hi\nthere' | string split0)
set -S lines
# $lines: set in global scope, unexported, with 1 elements
# $lines[1]: length=9 value=|hi\nthere\n|

This is noted in the document:

If the output is piped to string split or string split0 as the last step, those splits are used as they appear instead of splitting lines.

like image 3
wataash Avatar answered Oct 13 '22 19:10

wataash