361

Tôi muốn tham gia kết quả của ls -1một dòng và phân định nó với bất cứ điều gì tôi muốn.

Có bất kỳ lệnh Linux tiêu chuẩn nào tôi có thể sử dụng để đạt được điều này không?

|
549

Tương tự như tùy chọn đầu tiên nhưng bỏ qua dấu phân cách

ls -1 | paste -sd "," -
|
342

EDIT : Đơn giản là " ls -m " Nếu bạn muốn dấu phân cách của bạn là dấu phẩy

Ah, sức mạnh và sự đơn giản!

ls -1 | tr '\n' ','

Thay đổi dấu phẩy " , " thành bất cứ điều gì bạn muốn. Lưu ý rằng điều này bao gồm một "dấu phẩy"

|
19

Tôi nghĩ rằng điều này là tuyệt vời

ls -1 | awk 'ORS=","'

ORS là "dấu tách bản ghi đầu ra", vì vậy bây giờ các dòng của bạn sẽ được nối bằng dấu phẩy.

|
19

Điều này thay thế dấu phẩy cuối cùng bằng một dòng mới:

ls -1 | tr '\n' ',' | sed 's/,$/\n/'

ls -m bao gồm các dòng mới ở ký tự chiều rộng màn hình (ví dụ thứ 80).

Chủ yếu là Bash (chỉ lslà bên ngoài):

saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS

Sử dụng readarray(aka mapfile) trong Bash 4:

readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS

Cảm ơn gniourf_gniourf cho các đề xuất.

|
  • 1

    Điều này sẽ không chăm sóc các tập tin với khoảng trắng trong tên. Hãy thử cái này: dir = / tmp / testdir; rm -rf $ dir && mkdir $ dir && cd / $ dir && touch "đây là một tệp" this_is_another_file && ls -1 && files = ($ (ls -1)) && list = $ {files [@] /% / ,} && list = $ {list% *,} && echo $ list

    – Võ Quỳnh Thơ 13:55:10 23/10/2014
  • 1

    @dimir: Nhiều câu trả lời cho câu hỏi này bị vấn đề này. Tôi đã chỉnh sửa câu trả lời của mình để cho phép tên tệp có tab hoặc dấu cách, nhưng không phải dòng mới.

    – Hồ Đắc Tâm 15:58:43 23/10/2014
  • 1

    Phiên bản bash của bạn cũng bị mở rộng tên đường dẫn. Để xây dựng một mảng từ các dòng, vui lòng xem xét sử dụng mapfile(Bash 4) là : mapfile -t files < <(ls -1). Không cần phải mân mê với IFS. Và nó cũng ngắn hơn.

    – Phan Kim Thủy 16:08:37 23/10/2014
  • 1

    Và khi bạn có mảng của mình, bạn có thể sử dụng IFSđể tham gia các trường : saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS. Hoặc sử dụng một phương thức khác nếu bạn muốn một dấu phân cách có nhiều ký tự đó.

    – Bùi Bạch Yến 16:10:31 23/10/2014
  • 1

    @gniourf_gniourf: Tôi đã bao gồm các đề xuất của bạn trong câu trả lời của tôi. Cảm ơn.

    – Trịnh Phương Hiền 16:38:25 23/10/2014
14

Sự kết hợp của thiết lập IFSvà sử dụng "$*"có thể làm những gì bạn muốn. Tôi đang sử dụng một lớp con nên tôi không can thiệp vào $ IFS của shell này

(set -- *; IFS=,; echo "$*")

Để nắm bắt đầu ra,

output=$(set -- *; IFS=,; echo "$*")
|
  • 1

    Bạn có thêm một số thông tin liên quan đến cách làm setviệc? Trông hơi giống voodoo với tôi. Nhìn nông cạn man setcũng không cho tôi nhiều thông tin.

    – Võ Quỳnh Thơ 18:08:18 12/09/2013
  • 1

    Nếu bạn đưa ra setmột loạt các đối số nhưng không có tùy chọn, nó sẽ đặt các tham số vị trí ($ 1, $ 2, ...). --có để bảo vệ settrong trường hợp đối số đầu tiên (hoặc tên tệp trong trường hợp này) xảy ra để bắt đầu bằng dấu gạch ngang. Xem mô tả của --tùy chọn trong help set. Tôi tìm thấy các tham số vị trí một cách thuận tiện để xử lý một danh sách các thứ. Tôi cũng có thể đã thực hiện điều này với một mảng:output=$( files=(*); IFS=,; echo "${files[*]}" )

    – Hồ Đắc Tâm 18:16:23 12/09/2013
  • 1

    Điều này thật tuyệt vì nó không yêu cầu thực hiện bất kỳ chương trình bổ sung nào và nó hoạt động với tên tệp có chứa khoảng trắng hoặc thậm chí là dòng mới.

    – Phan Kim Thủy 22:26:02 21/01/2015
  • 1

    @EhteshChoudhury Như type setsẽ nói với bạn , set is a shell builtin. Vì vậy, man setsẽ không giúp đỡ, nhưng help setsẽ làm. Trả lời: "- Gán mọi đối số còn lại cho các tham số vị trí."

    – Bùi Bạch Yến 15:01:06 30/03/2016
  • 1

    Sau một set -- *. Trì hoãn mở rộng *một cấp độ, bạn có thể nhận được đầu ra chính xác mà không cần vỏ phụ : IFS=',' eval echo '"$*"'. Tất nhiên điều đó sẽ thay đổi các tham số vị trí.

    – Trịnh Phương Hiền 20:01:50 31/01/2017
12

Phân tích cú pháp lsnói chung không được khuyến khích , vì vậy cách tốt hơn là sử dụng find, ví dụ:

find . -type f -print0 | tr '\0' ','

Hoặc bằng cách sử dụng findpaste:

find . -type f | paste -d, -s

Để tham gia chung nhiều dòng (không liên quan đến hệ thống tệp), hãy kiểm tra: ngắn gọn và di động , hãy tham gia vào dòng trên Unix dòng lệnh Unix .

|
9

Đừng phát minh lại bánh xe.

ls -m

Nó làm chính xác điều đó.

|
  • 1

    OP muốn bất kỳ dấu phân cách nào, do đó bạn vẫn cần một tr để chuyển đổi dấu phẩy. Nó cũng thêm một khoảng trắng sau dấu phẩy tức là file1, file2, file3

    – Võ Quỳnh Thơ 08:50:11 26/04/2013
  • 1

    vì vậy, sử dụng ls -mtrxóa khoảng trắng sau dấu phẩy bạn sẽ làmls -m | tr -d ' '

    – Hồ Đắc Tâm 12:33:57 30/04/2013
  • 1

    việc sử dụng tr sẽ xóa khoảng trắng bên trong tên tệp. tốt hơn để sử dụngsed 's/, /,/g

    – Phan Kim Thủy 10:45:00 07/05/2013
7

Lệnh này dành cho người hâm mộ PERL:

ls -1 | perl -l40pe0

Ở đây 40 là mã bát phân bát phân cho không gian.

-p sẽ xử lý từng dòng và in

-l sẽ đảm nhiệm việc thay thế dấu vết \ n bằng ký tự ascii mà chúng tôi cung cấp.

-e là để thông báo cho PERL chúng tôi đang thực hiện dòng lệnh.

0 có nghĩa là thực sự không có lệnh để thực thi.

perl -e0 giống như perl -e ''

|
7

chỉ cần bash

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

Để tránh nhầm lẫn dòng mới tiềm năng cho tr, chúng tôi có thể thêm cờ -b vào ls:

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

Có vẻ như các câu trả lời đã tồn tại.

Nếu bạn muốn a, b, cđịnh dạng, hãy sử dụng ls -m( câu trả lời của Tulains Córdova )

Hoặc nếu bạn muốn a b cđịnh dạng, hãy sử dụng ls | xargs(phiên bản mô phỏng câu trả lời của Chris J )

Hoặc nếu bạn muốn bất kỳ dấu phân cách nào khác |, hãy sử dụng ls | paste -sd'|'(áp dụng câu trả lời của Artem )

|
3

Cách quyến rũ,

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

Lưu ý :

Đây là tuyến tính phức tạp, chỉ thay thế một lần sau khi tất cả các dòng được nối vào Không gian mẫu của sed.

Câu trả lời của @ AnandRajaseka và một số câu trả lời tương tự khác, chẳng hạn như ở đây , là O (n²), vì sed phải thay thế mỗi khi một dòng mới được thêm vào Không gian mẫu.

Để so sánh,

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
|
3
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]

Giải trình:

-e- biểu thị một lệnh được thực thi
:a- là nhãn
/$/N- xác định phạm vi của trận đấu cho dòng mở rộng hiện tại và (N)
s/\n/\\n/;- thay thế tất cả EOL bằng \n
ta;- nhãn goto a nếu khớp thành công

Lấy từ blog của tôi .

|
3

Nếu phiên bản xargs của bạn hỗ trợ cờ -d thì nó sẽ hoạt động

ls  | xargs -d, -L 1 echo

-d là cờ phân cách

Nếu bạn không có -d, thì bạn có thể thử cách sau

ls | xargs -I {} echo {}, | xargs echo

Các xargs đầu tiên cho phép bạn chỉ định dấu phân cách của bạn là dấu phẩy trong ví dụ này.

|
  • 1

    -dchỉ định dấu phân cách đầu vào với GNU xargs, vì vậy sẽ không hoạt động. Ví dụ thứ hai thể hiện vấn đề tương tự như các giải pháp khác ở đây về dấu phân cách đi lạc ở cuối.

    – Võ Quỳnh Thơ 15:09:02 13/09/2012
2

lstạo ra một đầu ra cột khi được kết nối với một đường ống, do đó, -1dự phòng.

Đây là một câu trả lời perl khác bằng cách sử dụng joinhàm dựng sẵn không để lại dấu phân cách:

ls | perl -F'\n' -0777 -anE 'say join ",", @F'

Việc tối nghĩa -0777làm cho perl đọc tất cả các đầu vào trước khi chạy chương trình.

sed thay thế mà không để lại một dấu phân cách

ls | sed '$!s/$/,/' | tr -d '\n'
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.