ฉันต้องการที่จะเข้าร่วมผลลัพธ์ของการls -1
เป็นหนึ่งบรรทัดและคั่นด้วยสิ่งที่ฉันต้องการ
มีคำสั่ง Linux มาตรฐานที่ฉันสามารถใช้เพื่อให้บรรลุนี้
ฉันต้องการที่จะเข้าร่วมผลลัพธ์ของการls -1
เป็นหนึ่งบรรทัดและคั่นด้วยสิ่งที่ฉันต้องการ
มีคำสั่ง Linux มาตรฐานที่ฉันสามารถใช้เพื่อให้บรรลุนี้
คำตอบ:
คล้ายกับตัวเลือกแรก แต่ไม่ใช้ตัวคั่นต่อท้าย
ls -1 | paste -sd "," -
paste
ได้รับ-
(เข้ามาตรฐาน) paste (GNU coreutils) 8.22
เป็นค่าเริ่มต้นอย่างน้อยในของฉัน
"\0"
ดังนั้นpaste -sd "\0" -
ทำงานได้ดีสำหรับฉัน!
แก้ไข : เพียงแค่ " ls -m " หากคุณต้องการให้ตัวคั่นของคุณเป็นจุลภาค
อ๊ะพลังและความเรียบง่าย!
ls -1 | tr '\n' ','
เปลี่ยนเครื่องหมายจุลภาค " , " เป็นสิ่งที่คุณต้องการ โปรดทราบว่าสิ่งนี้รวมถึง "เครื่องหมายจุลภาคต่อท้าย"
\n
อยู่ในนั้นมันจะแทนที่ด้วย
ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
อาจจะมีประสิทธิภาพมากขึ้นเล็กน้อยด้วยตัวละครที่สิ้นสุด:ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
หลังจากtr
ดูเหมือนว่าจะลบสัญลักษณ์ล่าสุดเท่านั้นดูเหมือนจะไม่สมเหตุสมผล ฉันไปกับls -1 | tr '\n' ',' | head -c -1
สิ่งนี้จะแทนที่เครื่องหมายจุลภาคสุดท้ายด้วยการขึ้นบรรทัดใหม่:
ls -1 | tr '\n' ',' | sed 's/,$/\n/'
ls -m
รวมบรรทัดใหม่ที่อักขระที่มีความกว้างหน้าจอ (ตัวอย่างที่ 80)
Bash ส่วนใหญ่ ( ls
ภายนอกเท่านั้น):
saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS
การใช้readarray
(aka mapfile
) ใน Bash 4:
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
ขอบคุณ gniourf_gniourf สำหรับคำแนะนำ
mapfile
(ทุบตี≥4) mapfile -t files < <(ls -1)
รวม: IFS
ไม่จำเป็นต้องคุ้นเคยกับ และมันก็สั้นลงเช่นกัน
IFS
saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS
หรือใช้วิธีอื่นถ้าคุณต้องการให้ตัวคั่นมีอักขระมากกว่าหนึ่งตัว
ฉันคิดว่าอันนี้ยอดเยี่ยม
ls -1 | awk 'ORS=","'
ORS คือ "ตัวคั่นเร็กคอร์ดเอาต์พุต" ดังนั้นตอนนี้บรรทัดของคุณจะถูกรวมเข้ากับเครื่องหมายจุลภาค
" OR "
)
การรวมกันของการตั้งค่าIFS
และการใช้"$*"
สามารถทำสิ่งที่คุณต้องการ ฉันใช้ subshell ดังนั้นฉันจะไม่เข้าไปยุ่งกับ $ IFS ของ shell นี้
(set -- *; IFS=,; echo "$*")
ในการจับเอาตพุต
output=$(set -- *; IFS=,; echo "$*")
set
ทำงานบ้างไหม? ดูเหมือนจะเป็นของขึ้นเล็กน้อยสำหรับฉัน การมองตื้นman set
ก็ไม่ได้ทำให้ฉันมีข้อมูลมากนัก
set
อาร์กิวเมนต์จำนวนมาก แต่ไม่มีตัวเลือกมันจะตั้งค่าพารามิเตอร์ตำแหน่ง ($ 1, $ 2, ... ) --
มีการป้องกันset
ในกรณีที่อาร์กิวเมนต์แรก (หรือชื่อไฟล์ในกรณีนี้) เกิดขึ้นเพื่อเริ่มต้นด้วยเส้นประ ดูรายละเอียดของตัวเลือกใน--
help set
ฉันค้นหาพารามิเตอร์ตำแหน่งเป็นวิธีที่สะดวกในการจัดการรายการสิ่งต่าง ๆ ฉันสามารถใช้สิ่งนี้กับอาเรย์ได้ด้วยoutput=$( files=(*); IFS=,; echo "${files[*]}" )
type set
set is a shell builtin
ดังนั้นman set
จะไม่ช่วย แต่help set
จะทำ คำตอบ: "- กำหนดอาร์กิวเมนต์ที่เหลือใด ๆ ให้กับพารามิเตอร์ตำแหน่ง"
set -- *
. การล่าช้าในการขยายตัวของระดับหนึ่งที่คุณอาจได้รับการส่งออกที่ถูกต้องโดยไม่จำเป็นต้องของเปลือกย่อยนี้:*
IFS=',' eval echo '"$*"'
แน่นอนว่าจะเปลี่ยนพารามิเตอร์ตำแหน่ง
ไม่แนะนำให้ใช้การแยกวิเคราะห์ls
โดยทั่วไปดังนั้นวิธีที่ดีกว่าคือใช้เช่น:find
find . -type f -print0 | tr '\0' ','
หรือโดยการใช้find
และpaste
:
find . -type f | paste -d, -s
สำหรับการเข้าร่วมทั่วไปหลายบรรทัด (ที่ไม่เกี่ยวข้องกับระบบแฟ้ม) การตรวจสอบ: กระชับและแบบพกพา“เข้าร่วม” บนระบบปฏิบัติการยูนิกซ์บรรทัดคำสั่ง
อย่าประดิษฐ์ล้อใหม่
ls -m
มันทำอย่างนั้น
ls -m
และtr
เพื่อลบช่องว่างหลังจากเครื่องหมายจุลภาคคุณจะทำอย่างไรls -m | tr -d ' '
sed 's/, /,/g
แค่ทุบตี
mystring=$(printf "%s|" *)
echo ${mystring%|}
|
@camh
bash
และ gnu coreutilsprintf
printf -v
จะใช้ได้เฉพาะใน bash เท่านั้นในขณะที่คำตอบที่นำเสนอใช้ได้กับเชลล์หลายประเภท
|
โดยมีเงื่อนไขว่าทั้งสองบรรทัดถูกใช้: printf -v mystring "%s|" * ; echo ${mystring%|}
.
คำสั่งนี้สำหรับแฟน ๆ PERL:
ls -1 | perl -l40pe0
นี่คือ 40 เป็นรหัสเลขฐานแปดสำหรับพื้นที่
-p จะประมวลผลทีละบรรทัดและพิมพ์
-l จะดูแลการแทนที่ส่วนท้าย \ n ด้วยอักขระ ascii ที่เราให้
-e เป็นการแจ้ง PERL ที่เรากำลังดำเนินการกับ command line
0 หมายความว่าไม่มีคำสั่งให้ดำเนินการ
perl -e0 เหมือนกับ perl -e ''
เพื่อหลีกเลี่ยงความสับสนของบรรทัดใหม่สำหรับ tr เราสามารถเพิ่มแฟล็ก -b ใน ls:
ls -1b | tr '\n' ';'
ดูเหมือนว่ามีคำตอบอยู่แล้ว
ถ้าคุณต้องการ
a, b, c
ฟอร์แมตให้ใช้ls -m
( คำตอบของ Tulains Córdova )
หรือถ้าคุณต้องการa b c
ฟอร์แมตให้ใช้ls | xargs
( คำตอบของChris Jเวอร์ชันที่แปลแล้ว)
หรือถ้าคุณต้องการตัวคั่นอื่น ๆ|
ให้ใช้ls | paste -sd'|'
(การประยุกต์ใช้คำตอบของ Artem )
เพิ่มด้านบนของคำตอบ majkinetor นี่คือวิธีการลบตัวคั่นต่อท้าย (เนื่องจากฉันยังไม่สามารถแสดงความคิดเห็นภายใต้คำตอบของเขา):
ls -1 | awk 'ORS=","' | head -c -1
เพียงแค่ลบจำนวนไบต์ต่อท้ายที่ตัวคั่นของคุณนับ
ฉันชอบวิธีนี้เพราะฉันสามารถใช้ตัวคั่นหลายตัว + ประโยชน์อื่น ๆ ของawk
:
ls -1 | awk 'ORS=", "' | head -c -2
แก้ไข
ดังที่ Peter สังเกตเห็นการนับจำนวนลบจะไม่ได้รับการสนับสนุนในส่วนหัวของ MacOS รุ่นดั้งเดิม อย่างไรก็ตามเรื่องนี้สามารถแก้ไขได้ง่าย
coreutils
ก่อนติดตั้ง "GNU Core Utilities เป็นยูทิลิตี้ไฟล์เชลล์และการจัดการข้อความพื้นฐานของระบบปฏิบัติการ GNU"
brew install coreutils
คำสั่งที่ให้บริการโดย MacOS จะถูกติดตั้งด้วยคำนำหน้า "g" ตัวอย่างเช่นgls
เช่น
เมื่อคุณทำสิ่งนี้แล้วคุณสามารถใช้ghead
ซึ่งมีจำนวนลบไบต์หรือดีกว่าทำนามแฝง:
alias head="ghead"
วิธีที่ใจเย็น ๆ
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
หมายเหตุ :
นี่คือเส้นตรงในความซับซ้อนการแทนที่เพียงครั้งเดียวหลังจากที่ทุกบรรทัดถูกผนวกเข้ากับพื้นที่รูปแบบของ sed
@ คำตอบของ AnandRajaseka และคำตอบอื่น ๆ ที่คล้ายกันเช่นที่นี่คือ O (n²) เนื่องจาก sed ต้องทำการแทนที่ทุกครั้งที่มีการต่อบรรทัดใหม่เข้ากับ Pattern Space
เปรียบเทียบ,
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
หากเวอร์ชัน xargs ของคุณรองรับแฟล็ก -d สิ่งนี้จะทำงานได้
ls | xargs -d, -L 1 echo
-d เป็นธงตัวคั่น
หากคุณไม่มี -d คุณสามารถลองทำสิ่งต่อไปนี้
ls | xargs -I {} echo {}, | xargs echo
xargs แรกช่วยให้คุณระบุตัวคั่นซึ่งเป็นเครื่องหมายจุลภาคในตัวอย่างนี้
-d
ระบุตัวคั่นอินพุตด้วย GNU xargs ดังนั้นจะไม่ทำงาน ตัวอย่างที่สองแสดงปัญหาเช่นเดียวกับโซลูชันอื่น ๆ ที่นี่ของตัวคั่นหลงทางในตอนท้าย
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]
คำอธิบาย:
-e
- หมายถึงคำสั่งที่จะดำเนินการ
:a
- เป็นเลเบล
/$/N
- กำหนดขอบเขตของการจับคู่สำหรับกระแสในปัจจุบันและ (N) สายต่อ
s/\n/\\n/;
- แทนที่ EOL ทั้งหมดด้วย\n
ta;
- goto label a หากการแข่งขันประสบความสำเร็จ
คุณสามารถใช้ได้:
ls -1 | perl -pe 's/\n$/some_delimiter/'
ls
สร้างเอาต์พุตคอลัมน์หนึ่งเมื่อเชื่อมต่อกับไพพ์ดังนั้น -1
ซ้ำซ้อน
ต่อไปนี้เป็นคำตอบสำหรับ perl อื่น ๆ ที่ใช้join
ฟังก์ชันbuiltin ซึ่งไม่ปล่อยให้ตัวคั่นต่อท้าย:
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
ความคลุมเครือ -0777
ทำให้ Perl อ่านอินพุตทั้งหมดก่อนที่จะเรียกใช้โปรแกรม
ทางเลือก sed ที่ไม่ปล่อยให้ตัวคั่นต่อท้าย
ls | sed '$!s/$/,/' | tr -d '\n'
ls
มีตัวเลือก-m
ในการกำหนดเขตเอาท์พุทด้วย", "
เครื่องหมายจุลภาคและเว้นวรรค
ls -m | tr -d ' ' | tr ',' ';'
การวางท่อผลลัพธ์นี้tr
เพื่อลบพื้นที่หรือเครื่องหมายจุลภาคจะอนุญาตให้คุณไพพ์ผลลัพธ์อีกครั้งtr
เพื่อแทนที่ตัวคั่น
ในตัวอย่างของฉันฉันแทนที่ตัวคั่น,
ด้วยตัวคั่น;
แทนที่;
ด้วยตัวคั่นตัวอักษรตัวใดตัวหนึ่งที่คุณต้องการเนื่องจาก tr เฉพาะบัญชีสำหรับอักขระตัวแรกในสตริงที่คุณส่งเป็นอาร์กิวเมนต์
คุณสามารถใช้ chomp เพื่อรวมหลายบรรทัดในบรรทัดเดียว:
perl -e 'ในขณะที่ (<>) {if (/ \ $ /) {chomp; } print;} 'bad0> test
ใส่เงื่อนไขการแบ่งบรรทัดในถ้า statement.It สามารถเป็นอักขระพิเศษหรือตัวคั่นใด ๆ
Perl เวอร์ชันด่วนพร้อมการจัดการสแลชต่อท้าย:
ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'
อธิบาย:
ls -1 | paste -s -d ":" -
ไม่แน่ใจว่าเป็นของสากลที่มีการวางทั้งหมดหรือไม่