- How to concatenate multiple lines of output to one line?
- 11 Answers 11
- The fastest and easiest ways I know to solve this problem:
- How can I print multiline output on the same line?
- 8 Answers 8
- Example run
- Some more details, for those who are interested.
- Printing a final newline.
- How do I list one filename per output line in Linux?
- 7 Answers 7
- How to join multiple lines of file names into one with custom delimiter?
- 22 Answers 22
- Output from ls has newlines but displays on a single line. Why?
- 2 Answers 2
How to concatenate multiple lines of output to one line?
If I run the command cat file | grep pattern , I get many lines of output. How do you concatenate all lines into one line, effectively replacing each «\n» with «\» » (end with » followed by space)?
cat file | grep pattern | xargs sed s/\n/ /g isn’t working for me.
11 Answers 11
Use tr ‘\n’ ‘ ‘ to translate all newline characters to spaces:
Note: grep reads files, cat concatenates files. Don’t cat file | grep !
Edit:
tr can only handle single character translations. You could use awk to change the output record separator like:
This would transform:
Piping output to xargs will concatenate each line of output to a single line with spaces:
Or any command, eg. ls | xargs . The default limit of xargs output is
4096 characters, but can be increased with eg. xargs -s 8192 .
In bash echo without quotes remove carriage returns, tabs and multiple spaces
This could be what you want
As to your edit, I’m not sure what it means, perhaps this?
(this assumes that
does not occur in file )
This is an example which produces output separate by commas. You can replace the comma by whatever separator you need.
Here is the method using ex editor (part of Vim):
Join all lines and print to the standard output:
Join all lines in-place (in the file):
Note: This will concatenate all lines inside the file it-self!
The fastest and easiest ways I know to solve this problem:
When we want to replace the new line character \n with the space:
xargs has own limits on the number of characters per line and the number of all characters combined, but we can increase them. Details can be found by running this command: xargs —show-limits and of course in the manual: man xargs
When we want to replace one character with another exactly one character:
When we want to replace one character with many characters:
First, we replace the newline characters \n for tildes
(or choose another unique character not present in the text), and then we replace the tilde characters with any other characters ( many_characters ) and we do it for each tilde (flag g ).
Источник
How can I print multiline output on the same line?
Is there a method to print multi-line output (single output) on the same line?
For example, if the output is:
Is it possible to print:
8 Answers 8
You can remove all occurrences of characters from a given set with tr -d . To remove the newline character use:
As always you can use input and output redirection and pipes to read from or write to files and other processes.
If you want to keep the last newline you can simply add it back with echo or printf ‘\n’ , e. g.:
Many ways. To illustrate, I have saved your example in file :
That removes all newline characters, including the last one though. You might instead want to do:
You can pipe your multiline output through awk
Example run
Also your_command | paste -sd » which preserves the trailing newline.
This answer has a solution to the problem you are trying to create: Why does bash remove \n in $(cat file)?
If you type cat myfile.txt you will see:
But if you type echo $(cat myfile.txt) you will see:
Note this method inserts a space where separate new lines used to be. This makes the output easier to read but doesn’t strictly adhere to your question scope.
If you want to use Perl for this, you can use its chomp function:
Some more details, for those who are interested.
You can pass one or more filenames as subsequent arguments.
In some cases you might not want to do that, but you can pipe or redirect to that command instead. (These abilities—and that caveat—all apply to any other perl -p or perl -n based solution, too.)
So, if you want to process output from running some-command :
This is potentially faster than the Perl command in terdon’s answer. Newline characters (represented by \n ) only appear at the end of lines in this situation—because they are what Perl is using to decide where each line ends. s/\n// searches through the entire line for newlines, while chomp just removes the one at the end (if any, as the very last line might or might not have one).
Performance might not really be the main reason to prefer chomp . The perl command in terdon’s answer would only be slightly slower unless you’re processing a huge file with very long lines. And if you need speed, David Foerster’s way is still probably faster. chomp is, however, exactly the right tool for this if you are using Perl, and I think the intent of chomp is clearer than that of s/\n// . Ultimately there’s probably no objective answer as to which is better.
Printing a final newline.
However, I do recommend against the use of command substitution ( $( ) ) just to ensure a trailing newline gets printed. Unless the text you’re processing is short, that’s likely to be quite slow—it has to collect all the text at once and then print it—and it makes your command harder to understand. Instead you can do as David Foerster suggested and run echo or printf ‘\n’ afterwards.
If you’re piping from or (as David Foerster shows) redirecting from that command, then you can enclose it in < ;>so that the output of both commands is taken together. If you’re just printing it to the terminal, then you can run it exactly as shown above. This works even if you’re piping or redirecting to the command, because echo / printf ‘\n’ does not actually read any input. That is, this works:
While here you cannot simply remove the < ;>:
Or, if you prefer, you can make perl print the final newline itself. Like enclosing the perl and echo commands in < ;>, this approach works even if you’re piping or redirecting from it (and, like all approaches, this works when you’re piping to it, too):
Note that the command in terdon’s answer works fine with these methods of printing the final newline, too. For example:
Источник
How do I list one filename per output line in Linux?
I’m using ls -a command to get the file names in a directory, but the output is in a single line.
I need a built-in alternative to get filenames, each on a new line, like this:
7 Answers 7
Use the -1 option (note this is a «one» digit, not a lowercase letter «L»), like this:
First, though, make sure your ls supports -1 . GNU coreutils (installed on standard Linux systems) and Solaris do; but if in doubt, use man ls or ls —help or check the documentation. E.g.:
Yes, you can easily make ls output one filename per line:
Explanation: The command ls senses if the output is to a terminal or to a file or pipe and adjusts accordingly.
So, if you pipe ls -a to python it should work without any special measures.
Ls is designed for human consumption, and you should not parse its output.
In shell scripts, there are a few cases where parsing the output of ls does work is the simplest way of achieving the desired effect. Since ls might mangle non-ASCII and control characters in file names, these cases are a subset of those that do not require obtaining a file name from ls .
In python, there is absolutely no reason to invoke ls . Python has all of ls ‘s functionality built-in. Use os.listdir to list the contents of a directory and os.stat or os to obtain file metadata. Other functions in the os modules are likely to be relevant to your problem as well.
If you’re accessing remote files over ssh, a reasonably robust way of listing file names is through sftp:
This prints one file name per line, and unlike the ls utility, sftp does not mangle nonprintable characters. You will still not be able to reliably list directories where a file name contains a newline, but that’s rarely done (remember this as a potential security issue, not a usability issue).
In python (beware that shell metacharacters must be escapes in remote_dir ):
For more complex interactions, look up sftp’s batch mode in the documentation.
On some systems (Linux, Mac OS X, perhaps some other unices, but definitely not Windows), a different approach is to mount a remote filesystem through ssh with sshfs, and then work locally.
Источник
How to join multiple lines of file names into one with custom delimiter?
I would like to join the result of ls -1 into one line and delimit it with whatever i want.
Are there any standard Linux commands I can use to achieve this?
22 Answers 22
Similar to the very first option but omits the trailing delimiter
EDIT: Simply «ls -m» If you want your delimiter to be a comma
Ah, the power and simplicity !
Change the comma «,» to whatever you want. Note that this includes a «trailing comma»
This replaces the last comma with a newline:
ls -m includes newlines at the screen-width character (80th for example).
Mostly Bash (only ls is external):
Using readarray (aka mapfile ) in Bash 4:
Thanks to gniourf_gniourf for the suggestions.
I think this one is awesome
ORS is the «output record separator» so now your lines will be joined with a comma.
Parsing ls in general is not advised, so alternative better way is to use find , for example:
Or by using find and paste :
For general joining multiple lines (not related to file system), check: Concise and portable “join” on the Unix command-line.
The combination of setting IFS and use of «$*» can do what you want. I’m using a subshell so I don’t interfere with this shell’s $IFS
To capture the output,
Don’t reinvent the wheel.
It does exactly that.
Adding on top of majkinetor’s answer, here is the way of removing trailing delimiter(since I cannot just comment under his answer yet):
Just remove as many trailing bytes as your delimiter counts for.
I like this approach because I can use multi character delimiters + other benefits of awk :
EDIT
As Peter has noticed, negative byte count is not supported in native MacOS version of head. This however can be easily fixed.
First, install coreutils . «The GNU Core Utilities are the basic file, shell and text manipulation utilities of the GNU operating system.»
Commands also provided by MacOS are installed with the prefix «g». For example gls .
Once you have done this you can use ghead which has negative byte count, or better, make alias:
Источник
Output from ls has newlines but displays on a single line. Why?
I think I may be overlooking a relatively fundamental point regarding shell. Output from the ls command by default separates output with newlines, but the shell displays the output on a single line.
Can anyone explain this to me? I had always presumed that the output was simply separated by spaces, but now that I see the output separated by newlines, I would expect the output to be displaying on separate lines.
od shows that the output is separated by newlines:
If newlines are present, then why doesn’t the output display as:
2 Answers 2
When you pipe the output, ls acts differently.
This fact is hidden away in the info documentation:
If standard output is a terminal, the output is in columns (sorted vertically) and control characters are output as question marks; otherwise, the output is listed one per line and control characters are output as-is.
To prove it, try running
This means that if you want the output to be guaranteed to be one file per line, regardless of whether it is being piped or redirected, you have to run
( -1 is the number one)
Or, you can force ls | less to output in columns by running
( -C is a capital C)
Your discovery highlights the primary reason why parsing the output of ls is always a bad idea. See Greg’s wiki for a full explanation.
Think of your problem in reverse. You noticed that ls sometimes does and sometimes doesn’t print newlines between it’s output. For use in scripts or when forced by the -1 flag, it does. One newline at the end of each file. What there is no guarantee that each newline represents a new file name. In fact, if a filename contains a newline itself, the output of ls will be absolutly un-parsable. Consider these filenames:
When you ls -1 a directory with that in it, you would get something that looked like this:
Would you not naturally asume there were four files? So would any scripts that parse the output of ls. In reality there are three files, one of the with a tricky name, but you would not be able to figure that out from the output of ls.*
* Unless you were using the -l flag and noticed the output was borked, but your scripts would still choke.
Источник