How to join multiple lines of file names into one

2019-01-04 05:01发布

问题:

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?

回答1:

Similar to the very first option but omits the trailing delimiter

ls -1 | paste -sd "," -


回答2:

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"



回答3:

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.



回答4:

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.



回答5:

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 "$*")


回答6:

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.



回答7:

Don't reinvent the wheel.

ls -m

It does exactly that.



回答8:

just bash

mystring=$(printf "%s|" *)
echo ${mystring%|}


回答9:

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 ' '



回答10:

To avoid potential newline confusion for tr we could add the -b flag to ls:

ls -1b | tr '\n' ';'


回答11:

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.



回答12:

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)



回答13:

You can use:

ls -1 | perl -pe 's/\n$/some_delimiter/'


回答14:

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.



回答15:

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'


回答16:

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


回答17:

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


回答18:

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.



回答19:

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.



标签: