มีคำสั่งเช่นเดียวกับcatใน linux ซึ่งสามารถส่งคืนจำนวนอักขระที่ระบุจากไฟล์ได้หรือไม่?
เช่นฉันมีไฟล์ข้อความเช่น:
Hello world
this is the second line
this is the third line
และฉันต้องการบางอย่างที่จะคืนค่าอักขระ 5 ตัวแรกซึ่งจะเป็น "สวัสดี"
ขอบคุณ
มีคำสั่งเช่นเดียวกับcatใน linux ซึ่งสามารถส่งคืนจำนวนอักขระที่ระบุจากไฟล์ได้หรือไม่?
เช่นฉันมีไฟล์ข้อความเช่น:
Hello world
this is the second line
this is the third line
และฉันต้องการบางอย่างที่จะคืนค่าอักขระ 5 ตัวแรกซึ่งจะเป็น "สวัสดี"
ขอบคุณ
คำตอบ:
head ได้ผลเช่นกัน:
head -c 100 file # returns the first 100 bytes in the file
.. จะแยก 100 ไบต์แรกและส่งคืน
สิ่งที่ดีในการใช้headสำหรับสิ่งนี้คือไวยากรณ์สำหรับการtailจับคู่:
tail -c 100 file # returns the last 100 bytes in the file
คุณสามารถรวมสิ่งเหล่านี้เพื่อรับช่วงของไบต์ ตัวอย่างเช่นหากต้องการรับ100 ไบต์ที่สองจากไฟล์ให้อ่าน 200 แรกด้วยheadและใช้ tail เพื่อรับ 100 สุดท้าย:
head -c 200 file | tail -c 100
headแล้วใช้tailเพื่อรับ 10 ตัวสุดท้ายเช่น:head -c 20 file | tail -c 10
คุณสามารถใช้ dd เพื่อแยกส่วนของไบต์โดยพลการ
ตัวอย่างเช่น,
dd skip=1234 count=5 bs=1
จะคัดลอกไบต์ 1235 ถึง 1239 จากอินพุตไปยังเอาต์พุตและทิ้งส่วนที่เหลือ
หากต้องการรับห้าไบต์แรกจากอินพุตมาตรฐานให้ทำ:
dd count=5 bs=1
โปรดทราบว่าหากคุณต้องการระบุชื่อไฟล์อินพุต dd มีการแยกวิเคราะห์อาร์กิวเมนต์แบบเก่าดังนั้นคุณต้องทำดังนี้
dd count=5 bs=1 if=filename
โปรดทราบด้วยว่า dd ประกาศอย่างเปิดเผยว่ามันทำอะไรเพื่อที่จะทิ้งสิ่งนั้นไปให้ทำ:
dd count=5 bs=1 2>&-
หรือ
dd count=5 bs=1 2>/dev/null
dd bs=1บังคับให้ dd อ่านและเขียนทีละอักขระซึ่งช้ากว่าheadเมื่อ count มีขนาดใหญ่มาก ไม่สามารถสังเกตได้สำหรับ count = 5 แม้ว่า
ddดูเหมือนว่าจะทำเคล็ดลับได้ .. ไชโย!
head -cใช้dd bs=5 count=1วิธีการนี้
หัว :
head - เอาต์พุตส่วนแรกของไฟล์
หัวหน้า [ OPTION ] ... [ FILE ] ...
พิมพ์ 10 บรรทัดแรกของแต่ละ FILE ไปยังเอาต์พุตมาตรฐาน ด้วยไฟล์มากกว่าหนึ่งไฟล์ให้แต่ละไฟล์นำหน้าด้วยส่วนหัวที่ให้ชื่อไฟล์ หากไม่มี FILE หรือเมื่อ FILE อยู่ - ให้อ่านอินพุตมาตรฐาน
อาร์กิวเมนต์ที่จำเป็นสำหรับตัวเลือกแบบยาวนั้นจำเป็นสำหรับตัวเลือกสั้น ๆ เช่นกัน
-c , --bytes = [-] N
พิมพ์ N ไบต์แรกของแต่ละไฟล์ ด้วย "-" นำหน้าให้พิมพ์ทั้งหมดยกเว้น N ไบต์สุดท้ายของแต่ละไฟล์
หัวหรือหางก็ทำได้เช่นกัน:
หัว -c X
พิมพ์ X ไบต์แรก (ไม่จำเป็นต้องเป็นอักขระหากเป็นไฟล์ UTF-16) ของไฟล์ tail จะทำเช่นเดียวกันยกเว้น X ไบต์สุดท้าย
สิ่งนี้ (และตัด) เป็นแบบพกพา
head -Line_number file_name | tail -1 |cut -c Num_of_chars
สคริปต์นี้ให้จำนวนอักขระที่แน่นอนจากบรรทัดและตำแหน่งเฉพาะเช่น:
head -5 tst.txt | tail -1 |cut -c 5-8
ให้ตัวอักษรในบรรทัดที่ 5 และตัวอักษร 5 ถึง 8 ของบรรทัดที่ 5
หมายเหตุ : tail -1ใช้เพื่อเลือกบรรทัดสุดท้ายที่แสดงโดยส่วนหัว
คุณยังสามารถดึงเส้นออกแล้วตัดออกเช่น:
ชื่อไฟล์ grep 'text' | ตัด -c 1-5
ฉันรู้ว่าคำตอบคือการตอบคำถามที่ถามเมื่อ 6 ปีที่แล้ว ...
แต่ฉันกำลังมองหาสิ่งที่คล้ายกันอยู่สองสามชั่วโมงแล้วพบว่า: cut -cทำอย่างนั้นพร้อมกับโบนัสเพิ่มเติมที่คุณสามารถระบุออฟเซ็ตได้
ตัด -c 1-5จะกลับมาสวัสดีและตัด -c 7-11จะกลับโลก ไม่จำเป็นต้องมีคำสั่งอื่นใด
แม้ว่าจะตอบ / ยอมรับเมื่อหลายปีก่อน แต่คำตอบที่ยอมรับในปัจจุบันนั้นถูกต้องสำหรับการเข้ารหัสแบบหนึ่งไบต์ต่ออักขระเช่น iso-8859-1 หรือสำหรับชุดย่อยแบบไบต์เดี่ยวของชุดอักขระไบต์ตัวแปร (เช่นอักขระละติน ภายใน UTF-8) แม้จะใช้การต่อแบบหลายไบต์แทนก็ยังใช้ได้เฉพาะกับการเข้ารหัสแบบหลายไบต์คงที่เช่น UTF-16 เนื่องจากตอนนี้ UTF-8 อยู่ในขั้นที่จะเป็นมาตรฐานสากลได้ดีและเมื่อดูรายชื่อภาษานี้ตามจำนวนเจ้าของภาษาและรายชื่อภาษา 30 อันดับแรกตามการใช้งานของเจ้าของภาษา / รองสิ่งสำคัญคือต้องชี้ให้เห็น เทคนิคที่เป็นมิตรกับอักขระแบบไบต์แบบง่าย (ไม่ใช่ไบต์) โดยใช้cut -cและtr/ sedกับคลาสอักขระ
เปรียบเทียบสิ่งต่อไปนี้ที่ล้มเหลวเป็นสองเท่าเนื่องจากข้อผิดพลาด / ข้อสันนิษฐานที่ใช้ภาษาละตินเป็นศูนย์กลางสองประการเกี่ยวกับปัญหาไบต์กับอักขระ (หนึ่งคือheadเทียบกับcutอีกปัญหาหนึ่งคือเทียบ[a-z][A-Z]กับ[:upper:][:lower:]):
$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$ head -c 1 | \
$ sed -e 's/[A-Z]/[a-z]/g'
[[unreadable binary mess, or nothing if the terminal filtered it]]
สำหรับสิ่งนี้ (หมายเหตุ: สิ่งนี้ใช้ได้ดีกับ FreeBSD แต่ทั้งสองcut& trบน GNU / Linux ยังคงสับสนภาษากรีกใน UTF-8 สำหรับฉัน):
$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$ cut -c 1 | \
$ tr '[:upper:]' '[:lower:]'
π
อีกคำตอบล่าสุดได้เสนอ "ตัด" แล้ว แต่เป็นเพียงเพราะปัญหาด้านข้างที่สามารถใช้เพื่อระบุการชดเชยตามอำเภอใจไม่ใช่เพราะอักขระที่เกี่ยวข้องโดยตรงกับปัญหาไบต์
หากคุณcutจัดการ-cกับการเข้ารหัสไบต์ตัวแปรไม่ถูกต้องสำหรับ " Xอักขระตัวแรก" (แทนที่Xด้วยตัวเลขของคุณ) คุณสามารถลอง:
sed -E -e '1 s/^(.{X}).*$/\1/' -e q - ซึ่ง จำกัด ไว้ที่บรรทัดแรกhead -n 1 | grep -E -o '^.{X}' - ซึ่ง จำกัด ไว้ที่บรรทัดแรกและเชื่อมโยงคำสั่งสองคำสั่งdd - ซึ่งได้รับการแนะนำในคำตอบอื่น ๆ แล้ว แต่ก็ยุ่งยากจริงๆsedสคริปต์ที่ซับซ้อนพร้อมด้วยบัฟเฟอร์หน้าต่างบานเลื่อนเพื่อจัดการกับอักขระที่กระจายอยู่ในหลายบรรทัด แต่อาจยุ่งยาก / เปราะบางมากกว่าการใช้สิ่งต่างๆเช่นddหากคุณtrไม่จัดการคลาสอักขระที่มีการเข้ารหัสไบต์ตัวแปรอย่างถูกต้องคุณสามารถลอง:
sed -E -e 's/[[:upper:]]/\L&/g (GNU เฉพาะ)printf 'Πού ' | cut -c 1แค่ส่งกลับคำพูดพล่อยๆ ... มันทำตัวเหมือน 'หัว'
นี่คือสคริปต์ง่ายๆที่สรุปโดยใช้ddแนวทางที่กล่าวถึงที่นี่:
#!/usr/bin/env bash
function show_help()
{
IT="
extracts characters X to Y from stdin or FILE
usage: X Y {FILE}
e.g.
2 10 /tmp/it => extract chars 2-10 from /tmp/it
EOF
"
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
FROM=$1
TO=$2
COUNT=`expr $TO - $FROM + 1`
if [ -z "$3" ]
then
dd skip=$FROM count=$COUNT bs=1 2>/dev/null
else
dd skip=$FROM count=$COUNT bs=1 if=$3 2>/dev/null
fi
mkfifo /tmp/test.fifo; echo "hello world">/tmp/test.fifo & head -c 5 /tmp/test.fifoยังบริโภค" world\n"ที่สูญหายไปตลอดกาล