Tôi muốn tham gia kết quả của ls -1
mộ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?
Helpex - Trao Đổi & Giúp Đỡ - là một trang web tổng hợp, chia sẻ kiến thức và hỏi đáp dành cho các lĩnh vực ở mọi cấp độ và các chuyên gia trong các lĩnh vực liên quan. Chỉ mất một phút để đăng ký.
Tham gia cộng đồngTương tự như tùy chọn đầu tiên nhưng bỏ qua dấu phân cách
ls -1 | paste -sd "," -
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"
+1, nhưng một phiên bản phức tạp hơn sẽ xử lý khác nhau lần cuối
– Hoàng Xuân Nam 09:24:31 04/05/2010@unicornaddict bạn có thể sử dụng -b hoặc -q cho ls để xử lý các trường hợp lạ như bạn đề cập.
– Trịnh Thất Cương 09:40:07 04/05/2010@ShreevatsaR: anh ta có nghĩa là không nối đuôi "," tôi tin. như vậyls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
@Chris: bạn sed
có thể hiệu quả hơn một chút với ký tự kết thúc:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
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.
Điều này đặc biệt tuyệt vời do xử lý các dấu tách bản ghi nhiều ký tự (ví dụ " OR "
:)
Đ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ỉ ls
là 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.
Đ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@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/2014Phiê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.
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ự đó.
@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/2014Sự kết hợp của thiết lập IFS
và 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 "$*")
Bạn có thêm một số thông tin liên quan đến cách làm set
việc? Trông hơi giống voodoo với tôi. Nhìn nông cạn man set
cũng không cho tôi nhiều thông tin.
Nếu bạn đưa ra set
mộ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ệ set
trong 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[*]}" )
Đ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@EhteshChoudhury Như type set
sẽ nói với bạn , set is a shell builtin
. Vì vậy, man set
sẽ không giúp đỡ, nhưng help set
sẽ làm. Trả lời: "- Gán mọi đối số còn lại cho các tham số vị trí."
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í.
Phân tích cú pháp ls
nó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 find
và paste
:
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 .
Đừng phát minh lại bánh xe.
ls -m
Nó làm chính xác điều đó.
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/2013vì vậy, sử dụng ls -m
và tr
xóa khoảng trắng sau dấu phẩy bạn sẽ làmls -m | tr -d ' '
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
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 ''
chỉ cần bash
mystring=$(printf "%s|" *)
echo ${mystring%|}
Hiệu quả hơn một chút sẽ là sử dụng "printf -v mystring"% s | "*" - để tránh một ngã ba cho $ ()
– Võ Quỳnh Thơ 09:56:41 09/05/2010@camh Nhưng printf -v
sẽ chỉ hoạt động trong bash, trong khi câu trả lời được trình bày hoạt động trên nhiều loại vỏ.
@Christopher Có, điều đó sẽ xóa dấu vết |
, miễn là cả hai dòng được sử dụng : printf -v mystring "%s|" * ; echo ${mystring%|}
.
Để 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' ';'
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 )
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
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 .
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.
-d
chỉ đị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.
ls
tạo ra một đầu ra cột khi được kết nối với một đường ống, do đó, -1
dự phòng.
Đây là một câu trả lời perl khác bằng cách sử dụng join
hà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 -0777
là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ũng giống như một ghi chú, phiên bản dán tôi đã thử yêu cầu một đối số "-" ở cuối để bảo nó đọc từ STDIN. ví dụ:
– Hoàng Xuân Nam 16:15:50 10/05/2012ls -1 | paste -s -d ":" -
Không chắc chắn nếu đó là phổ quát với tất cả các phiên bản dáncái này tốt hơn vì nó cho phép dấu phân cách trống :)
– Lý Hà My 23:05:44 15/08/2014Lưu ý
– Trịnh Thất Cương 13:19:45 29/07/2015paste
được-
(đầu vào tiêu chuẩn) như mặc định, ít nhất là trên của tôipaste (GNU coreutils) 8.22
.Tôi chỉ nâng cấp nó, đây là và bây giờ nó có cùng số phiếu với câu trả lời được chọn. ĐÂY LÀ CÂU TRẢ LỜI. không có dấu vết đo
– Vũ Chấn Hùng 13:23:05 14/09/2015Thay đổi cuộc đời tôi!
– Hoàng Hải Nguyên 07:17:56 16/10/2018