How to Preserve Line Breaks When Storing Command Output to a Variable

How to preserve line breaks when storing command output to a variable?

Quote your variables. Here is it why:

$ f="fafafda
> adffd
> adfadf
> adfafd
> afd"



$ echo $f
fafafda adffd adfadf adfafd afd



$ echo "$f"
fafafda
adffd
adfadf
adfafd
afd

Without quotes, the shell replaces $TEMP with the characters it contains (one of which is a newline). Then, before invoking echo shell splits that string into multiple arguments using the Internal Field Separator (IFS), and passes that resulting list of arguments to echo. By default, the IFS is set to whitespace (spaces, tabs, and newlines), so the shell chops your $TEMP string into arguments and it never gets to see the newline, because the shell considers it a separator, just like a space.

How to preserve new line in shell script output?

Maybe you should try something like this.

output_logs=`sh script2.sh $1 $2`
echo "$output_logs"

Note that this is different from echo $output_logs.

The double-quoted version of the variable preserves internal spacing of the value exactly as it is represented in the variable — newlines, tabs, multiple blanks and all — whereas the unquoted version replaces each sequence of one or more blanks, tabs and newlines with a single space.

How to preserve whitespace when saving command output to a Makefile variable?

I want to capture that output into a variable and then later print the
variable to a file.

There does not seem to be a way around make's mechanism to translate newlines in the shell command output into spaces. A bit of a hack that stays close to your original approach would be to have the shell convert newlines into some uncommon character (like \1) when assigning the output to the variable and then have it translate it back when echo-ing that variable to the file. Something like this:

OUTPUT=$(shell cowsay hello | tr '\n' '\1')

all:
@echo "$(OUTPUT)" | tr '\1' '\n' > output.txt

For me, this results in

$ make
$ cat output.txt
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||

How do I preserve line breaks from a command output and write it to a file using ansible copy module

- name: Play to run find command and capture its output to a file
hosts: localhost
connection: local
tasks:
- name: 'Run find command to fetch file rights {{inventory_hostname}}'
command: 'find /var/tmp/rhsm -type f -printf "{{ inventory_hostname }},%m,%p;\n"'
register: find_results
become: true
become_user: root
become_method: sudo

- name: Print to verify it works
debug:
msg: '{{find_results.stdout}}'

- name: Use copy module to create the file using output from the previous command.
copy:
dest: "/tmp/find_results.txt"
content: "{{ item }}"
with_items: "{{ find_results.stdout }}"
delegate_to: localhost
[rohtash@172 blockinfile]$ vi find.yml
[rohtash@172 blockinfile]$ ansible-playbook find.yml

PLAY [Play to run find command and capture its output to a file] ******************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************
ok: [localhost]

TASK [Run find command to fetch file rights localhost] ****************************************************************************************************************************************
changed: [localhost]

TASK [Print to verify it works] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "localhost,664,/var/tmp/rhsm/abc1;\nlocalhost,664,/var/tmp/rhsm/abc2;\nlocalhost,664,/var/tmp/rhsm/abc3;\nlocalhost,664,/var/tmp/rhsm/abc4;\nlocalhost,664,/var/tmp/rhsm/abc5;\nlocalhost,664,/var/tmp/rhsm/abc6;"
}

TASK [Use copy module to create the file using output from the previous command.] *************************************************************************************************************
changed: [localhost] => (item=localhost,664,/var/tmp/rhsm/abc1;
localhost,664,/var/tmp/rhsm/abc2;
localhost,664,/var/tmp/rhsm/abc3;
localhost,664,/var/tmp/rhsm/abc4;
localhost,664,/var/tmp/rhsm/abc5;
localhost,664,/var/tmp/rhsm/abc6;)

PLAY RECAP ************************************************************************************************************************************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0



[rohtash@172 blockinfile]$ cat /tmp/find_results.txt
localhost,664,/var/tmp/rhsm/abc1;
localhost,664,/var/tmp/rhsm/abc2;
localhost,664,/var/tmp/rhsm/abc3;
localhost,664,/var/tmp/rhsm/abc4;
localhost,664,/var/tmp/rhsm/abc5;
localhost,664,/var/tmp/rhsm/abc6;[rohtash@172 blockinfile]$

OR

dont use pipe after blockinfile. Use only find_results. stdout not stdout_lines like this.

[rohtash@172 blockinfile]$ ansible-playbook find_withblock.yml 

PLAY [Play to run find command and capture its output to a file] ******************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************
ok: [localhost]

TASK [Run find command to fetch file rights localhost] ****************************************************************************************************************************************
changed: [localhost]

TASK [Print to verify it works] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "localhost,664,/var/tmp/rhsm/abc1;\nlocalhost,664,/var/tmp/rhsm/abc2;\nlocalhost,664,/var/tmp/rhsm/abc3;\nlocalhost,664,/var/tmp/rhsm/abc4;\nlocalhost,664,/var/tmp/rhsm/abc5;\nlocalhost,664,/var/tmp/rhsm/abc6;"
}

TASK [Use blockinfile to do the same] *********************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP ************************************************************************************************************************************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[rohtash@172 blockinfile]$ cat /tmp/find_results_usingblocks.txt
# BEGIN ANSIBLE MANAGED BLOCK
localhost,664,/var/tmp/rhsm/abc1;
localhost,664,/var/tmp/rhsm/abc2;
localhost,664,/var/tmp/rhsm/abc3;
localhost,664,/var/tmp/rhsm/abc4;
localhost,664,/var/tmp/rhsm/abc5;
localhost,664,/var/tmp/rhsm/abc6;
# END ANSIBLE MANAGED BLOCK
[rohtash@172 blockinfile]$ cat find_withblock.yml
- name: Play to run find command and capture its output to a file
hosts: localhost
connection: local
tasks:
- name: 'Run find command to fetch file rights {{inventory_hostname}}'
command: 'find /var/tmp/rhsm -type f -printf "{{ inventory_hostname }},%m,%p;\n"'
register: find_results
become: true
become_user: root
become_method: sudo

- name: Print to verify it works
debug:
msg: '{{find_results.stdout}}'

- name: Use blockinfile to do the same
blockinfile:
path: "/tmp/find_results_usingblocks.txt"
block: "{{ find_results.stdout }}"
state: present
delegate_to: localhost

use whichever suits u best.

How can I store command output in a variable not on just one line?

You need to use quotes.

echo "$ports"

When bash sees the line without quotes, it performs word splitting. In other words, it's as if you executed:

echo 21/tcp open ftp\
22/tcp open ssh\
23/tcp open telnet

Which treats the newlines no differently that the spaces, and passes each argument to echo. It then writes each argument, separated by a single space.

How to preserve the format of command output after it is assigned to a variable in csh?

This is black magic but it works:

$ csh
% set g=`ls | sed -s ':a;N;$\\!ba;s/\n/\\n/g'`
% echo "$g"
% /bin/echo -e "$g"

The idea is to change the newlines by \n using sed. I used this trick to get it. Note that I had to double escape label !ba to tell csh that it is not an event.

You may replace ls by last -f /var/log/utx.log to check if it works for you.

linux. how to preserve lines when setting content of file to environment variable?

Yes:

temp=`cat [file]`
echo "$temp"

The magic is in the quotes around $temp; without them, echo gets these arguments:

echo line1\nline2\nlin3

The shell parsing algorithm will split the command line at white space, so echo sees three arguments. If you quote the variable, echo will see a single argument and the shell parsing won't touch the whitespace between the quotes.

Capturing multiple line output into a Bash variable

Actually, RESULT contains what you want — to demonstrate:

echo "$RESULT"

What you show is what you get from:

echo $RESULT

As noted in the comments, the difference is that (1) the double-quoted version of the variable (echo "$RESULT") preserves internal spacing of the value exactly as it is represented in the variable — newlines, tabs, multiple blanks and all — whereas (2) the unquoted version (echo $RESULT) replaces each sequence of one or more blanks, tabs and newlines with a single space. Thus (1) preserves the shape of the input variable, whereas (2) creates a potentially very long single line of output with 'words' separated by single spaces (where a 'word' is a sequence of non-whitespace characters; there needn't be any alphanumerics in any of the words).



Related Topics



Leave a reply



Submit