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?
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?
Similar to the very first option but omits the trailing delimiter
ls -1 | paste -sd "," -
EDIT: Simply "ls -m" If you want your delimiter to be a comma
Ah, the power and simplicity !
ls -1 | tr '\n' ','
Change the comma "," to whatever you want. Note that this includes a "trailing comma"
This replaces the last comma with a newline:
ls -1 | tr '\n' ',' | sed 's/,$/\n/'
ls -m
includes newlines at the screen-width character (80th for example).
Mostly Bash (only ls
is external):
saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS
Using readarray
(aka mapfile
) in Bash 4:
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
Thanks to gniourf_gniourf for the suggestions.
I think this one is awesome
ls -1 | awk 'ORS=","'
ORS is the "output record separator" so now your lines will be joined with a comma.
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
(set -- *; IFS=,; echo "$*")
To capture the output,
output=$(set -- *; IFS=,; echo "$*")
Parsing ls
in general is not advised, so alternative better way is to use find
, for example:
find . -type f -print0 | tr '\0' ','
Or by using find
and paste
:
find . -type f | paste -d, -s
For general joining multiple lines (not related to file system), check: Concise and portable “join” on the Unix command-line.
Don't reinvent the wheel.
ls -m
It does exactly that.
just bash
mystring=$(printf "%s|" *)
echo ${mystring%|}
This command is for the PERL fans :
ls -1 | perl -l40pe0
Here 40 is the octal ascii code for space.
-p will process line by line and print
-l will take care of replacing the trailing \n with the ascii character we provide.
-e is to inform PERL we are doing command line execution.
0 means that there is actually no command to execute.
perl -e0 is same as perl -e ' '
To avoid potential newline confusion for tr we could add the -b flag to ls:
ls -1b | tr '\n' ';'
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]
Explanation:
-e
- denotes a command to be executed
:a
- is a label
/$/N
- defines the scope of the match for the current and the (N)ext line
s/\n/\\n/;
- replaces all EOL with \n
ta;
- goto label a if the match is successful
Taken from my blog.
It looks like the answers already exist.
If you want
a, b, c
format, use ls -m
( Tulains Córdova’s answer)
Or if you want a b c
format, use ls | xargs
(simpified version of Chris J’s answer)
Or if you want any other delimiter like |
, use ls | paste -sd'|'
(application of Artem’s answer)
You can use:
ls -1 | perl -pe 's/\n$/some_delimiter/'
If you version of xargs supports the -d flag then this should work
ls | xargs -d, -L 1 echo
-d is the delimiter flag
If you do not have -d, then you can try the following
ls | xargs -I {} echo {}, | xargs echo
The first xargs allows you to specify your delimiter which is a comma in this example.
ls
produces one column output when connected to a pipe, so the -1
is redundant.
Here's another perl answer using the builtin join
function which doesn't leave a trailing delimiter:
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
The obscure -0777
makes perl read all the input before running the program.
sed alternative that doesn't leave a trailing delimiter
ls | sed '$!s/$/,/' | tr -d '\n'
The sed way,
sed -e ':a; N; $!ba; s/\n/,/g'
# :a # label called 'a'
# N # append next line into Pattern Space (see info sed)
# $!ba # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop
# s/\n/,/g # any substitution you want
Note:
This is linear in complexity, substituting only once after all lines are appended into sed's Pattern Space.
@AnandRajaseka's answer, and some other similar answers, such as here, are O(n²), because sed has to do substitute every time a new line is appended into the Pattern Space.
To compare,
seq 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
# linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
# quadratic, hung
Adding on top of majkinetor's answer, here is the way of removing trailing delimiter(since I cannot just comment under his answer yet):
ls -1 | awk 'ORS=","' | head -c -1
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
:
ls -1 | awk 'ORS=", "' | head -c -2
ls
has the option -m
to delimit the output with ", "
a comma and a space.
ls -m | tr -d ' ' | tr ',' ';'
piping this result to tr
to remove either the space or the comma will allow you to pipe the result again to tr
to replace the delimiter.
in my example i replace the delimiter ,
with the delimiter ;
replace ;
with whatever one character delimiter you prefer since tr only accounts for the first character in the strings you pass in as arguments.
You can use chomp to merge multiple line in single line:
perl -e 'while (<>) { if (/\$/ ) { chomp; } print ;}' bad0 >test
put line break condition in if statement.It can be special character or any delimiter.