วิธีรับคำแรกของสตริง


43

เมื่อฉัน'echo *' ได้รับผลลัพธ์ต่อไปนี้:

file1 file2 file3 ...

สิ่งที่ฉันต้องการคือการเลือกคำแรก ฉันจะดำเนินการต่อได้อย่างไร


1
@mattdm การใช้งานlsจะไม่ทำงานหากหนึ่งในชื่อไฟล์มีช่องว่าง
helpermethod

2
คุณกำหนดคำศัพท์อย่างไร หากเป็นไฟล์แรกSunset on a beach.jpgควรเป็นSunsetหรือชื่อไฟล์ทั้งหมดหรือไม่ เกี่ยวกับSea, sex and sun.oggอะไร Sea, Sea,หรือชื่อไฟล์ทั้งหมด?
Stéphane Chazelas

@attdm ls | head -1ให้สิ่งที่ฉันสุ่มa.patch p.pyซึ่งไม่ใช่คำแรกและไม่แม้แต่ไฟล์ตามลำดับตัวอักษร
phuclv

คำตอบ:


52

คุณสามารถไพพ์ผ่าน awk และทำให้มันสะท้อนคำแรก

echo * | head -n1 | awk '{print $1;}'

หรือคุณตัดสตริงและเลือกคำแรก:

echo *  | head -n1 | cut -d " " -f1

หรือคุณใช้มันจนหมดและลบมันทุกอย่างยกเว้นคำแรก

echo * | head -n1 | sed -e 's/\s.*$//'

เพิ่มการ| head -n1ตอบสนอง nitpickers ในกรณีที่สตริงของคุณมีการขึ้นบรรทัดใหม่| head -n1จะเลือกบรรทัดแรกก่อนคำสั่งที่สำคัญเลือกคำแรกจากสตริงที่ส่งผ่านไป


จะส่งคืนคำแรกของทุกบรรทัดไม่ใช่คำแรก
Stéphane Chazelas

2
ฉันสงสัยว่ามีกี่บรรทัดที่echo *สร้าง
Bananguin

ขึ้นอยู่กับจำนวนไฟล์ที่มีอักขระบรรทัดใหม่ในชื่อของพวกเขาหรือขึ้นอยู่กับสภาพแวดล้อมหรือวิธีการรวบรวมทุบตีหรือว่าบางไฟล์ที่เรียกว่า-eหรือ-ee... ปรากฏในรายการกี่ครั้งที่\nปรากฏในชื่อไฟล์ หากมีไฟล์ชื่อ-nมันอาจจะไม่ส่งคืนบรรทัดใด ๆ เลย ...
Stéphane Chazelas

เรายังพูดถึง bash และ 1. ปกติ bash จะไม่ผ่านสตริงที่มีการขึ้นบรรทัดใหม่เป็นหนึ่งสายที่มีบรรทัดใหม่ 2. มันยากมากและผิดปกติ (เป็นไปไม่ได้?) ที่จะมีการขึ้นบรรทัดใหม่ในชื่อไฟล์ 3. a \ n ใน ชื่อไฟล์จะปรากฏเป็น \ n 4. 3 สำหรับชื่อไฟล์ที่ขึ้นต้นด้วย - 5. แม้เมื่อเรียกด้วย -n หรือ -e echo จะเปิด stdout และปิดมันเมื่อทำเสร็จแน่นอนว่ามันจะส่งคืนบรรทัดและที่ อย่างน้อยหนึ่งสายสำหรับเรื่องที่ 6 ฉันแก้ไขคำแนะนำของฉันอย่างน้อยดูแลปัญหาหลายสาย
Bananguin

1
คะแนน 5 ทั้งหมดเป็นเท็จ ลองใน dir ที่ว่างเปล่า: touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'( xpg_echoเปิดใช้งานทุกที่ที่bashจำเป็นเพื่อให้สอดคล้องกับ Unix) และในไดเรกทอรีว่างอื่น: touch ./-n; bash -c 'echo * | wc -l'. บรรทัดคือลำดับของอักขระที่ยกเลิกโดยอักขระบรรทัดใหม่ หากechoไม่ส่งออกอักขระขึ้นบรรทัดใหม่ก็จะไม่ส่งออกบรรทัดใด ๆ พฤติกรรมของสาธารณูปโภคข้อความชอบcut, awkหรือsedเป็นที่ไม่ระบุถ้าใส่มีอักขระพิเศษหลังอักขระ newline ที่ผ่านมาและพฤติกรรมที่แตกต่างกันไปการใช้งาน
Stéphane Chazelas

18

สมมติว่าเชลล์ posixy ( /bin/shหรือ/bin/bashสามารถทำได้)

all=$(echo *)
first=${all%% *}

สร้าง${all%% *}เป็นตัวอย่างของการกำจัด substring %%วิธีลบการจับคู่ที่ยาวที่สุดของ*(เว้นวรรคตามด้วยอะไร) allจากปลายด้านขวามือของตัวแปร คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการจัดการสตริงที่นี่

วิธีแก้ปัญหานี้สันนิษฐานว่าตัวคั่นเป็นช่องว่าง หากคุณกำลังทำสิ่งนี้ด้วยชื่อไฟล์แล้วใด ๆ ที่มีช่องว่างจะทำลายมัน


ทำได้ดีนี่. แต่ฉันชอบเวอร์ชั่นอื่นที่เรียบง่ายและไม่แฮ็คมากขึ้นด้วยheadและcut
Anwar

4
IMO, head, cut & sed นั้นง่ายกว่า วางไข่เครื่องมืออื่นทำไมเมื่อทดแทนพารามิเตอร์ builtin ทำงานได้อย่างมีประสิทธิภาพ คำตอบนี้เป็นวิธีที่มีประสิทธิภาพและพกพาได้มากที่สุดในการเลือกคำแรกของรายการคำที่คั่นด้วยช่องว่าง (ซึ่ง OP ทั้งหมดขอมา)
Juan

7

สมมติว่าคุณต้องการชื่อไฟล์แรกและไม่ใช่คำแรกนี่คือวิธีที่ไม่ทำลายช่องว่าง:

shopt -s nullglob
files=(*)
printf '%s\n' "${files[0]}"

1
คำแรกก็ง่ายเช่นกัน:files=($(echo *))
Hauke ​​Laging

2
มันจะแตกกับ "-n", "-e", "-ne", "-Enenene" ... และขึ้นอยู่กับว่าbashคอมไพล์หรือสภาพแวดล้อมอย่างไรอาจเป็นอักขระแบ็กสแลช
Stéphane Chazelas

2
@HaukeLaging คุณจะต้องปิดการใช้งาน globbing text=$(echo *); set -f; files=($text)ไลค์: ไม่เช่นนั้นจะสามารถขยายไวด์การ์ดได้มากขึ้น
Stéphane Chazelas

3
และfiles=$(echo *); echo ${files%% *}
vdegenne

1
@memnoch_proxy มันจะทำลายชื่อไฟล์ที่มีช่องว่างใช้ด้วยความระมัดระวัง
Chris Down

5

คุณสามารถใช้พารามิเตอร์ตำแหน่ง

set -- *
echo "$1"

3
โปรดทราบว่าสิ่งนี้จะทำลายข้อโต้แย้งอื่น ๆ ในสคริปต์ของคุณเว้นแต่จะทำงานในขอบเขตเสริม มันจะขยายไปถึง*หากไม่มีไฟล์ในไดเรกทอรี
Chris Down

shopt -s nullglobจะจัดการกับมัน
เกล็นแจ็คแมน



โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.