อะไรคือ 'ฟิลด์' สำหรับคำสั่ง cut?


16

ตัวอย่างเช่นcutคำสั่งสามารถใช้พารามิเตอร์ -f ซึ่งเป็นไปตามman

เลือกเฉพาะฟิลด์เหล่านี้ พิมพ์บรรทัดใด ๆ ที่ไม่มีอักขระตัวคั่นยกเว้นระบุ -s ตัวเลือก

ในบริบทนี้เขตข้อมูลคืออะไร

คำตอบ:


19

ฟิลด์ "" ระยะมักจะเป็นครั้งที่เกี่ยวข้องกับเครื่องมือเช่นและcut awkเขตข้อมูลจะคล้ายกับคอลัมน์ที่มีมูลค่าของข้อมูลหากคุณใช้ข้อมูลและแยกออกโดยใช้อักขระเฉพาะ โดยทั่วไปตัวละครที่ใช้ทำสิ่งนี้คือSpaceโดยปกติตัวอักษรที่ใช้ในการทำเช่นนี้เป็น

อย่างไรก็ตามเป็นกรณีที่มีเครื่องมือส่วนใหญ่ก็สามารถกำหนดค่าได้ ตัวอย่างเช่น:

  • awk = awk -F"," ...- คั่นด้วยเครื่องหมายจุลภาค (เช่น, )
  • cut = cut -d"," ...- จะคั่นด้วยเครื่องหมายจุลภาค (เช่น,)

ตัวอย่าง

อันแรกนี้แสดงให้เห็นว่าawkจะแบ่งช่องว่างโดยอัตโนมัติอย่างไร

$ echo "The rain in Spain." | awk '{print $1" "$4}'
The Spain.

อันนี้แสดงให้เห็นว่าcutจะแยกช่องว่างได้อย่างไร

$ echo "The rain in Spain." | cut -d" " -f1,4
The Spain.

ที่นี่เรามีรายการคอลัมน์ข้อมูล CSV ที่เราใช้cutเพื่อส่งคืนคอลัมน์ 1 และ 4

$ echo "col1,col2,col3,co4" | cut -d"," -f1,4
col1,co4

Awk ก็สามารถทำได้เช่นกัน:

$ echo "col1,col2,col3,co4" | awk -F"," '{print $1","$4}'
col1,co4

Awk ยังเก่งกว่าเล็กน้อยในการรับมือกับตัวละครแยกต่าง ๆ นี่ก็จัดการกับTabsพร้อมกับSpacesที่พวกเขากำลังผสมระหว่างในเวลาเดียวกัน:

$ echo -e "The\t rain\t\t in Spain." | awk '{print $1" "$4}'
The Spain.

แล้วสวิตช์ -s เพื่อตัดล่ะ?

ด้วยความเคารพต่อสวิตช์นี้มันเพียงแค่บอกว่าcutจะไม่พิมพ์บรรทัดใด ๆ ที่ไม่มีอักขระตัวคั่นที่ระบุผ่าน-dสวิตช์

ตัวอย่าง

สมมติว่าเรามีไฟล์นี้

$ cat sample.txt 
This is a space string.
This is a space   and   tab string.
Thisstringcontainsneither.

หมายเหตุ:มีช่องว่างและแท็บในสตริงที่ 2 ด้านบน

ตอนนี้เมื่อเราดำเนินการเหล่านี้โดยใช้สายcutที่มีและไม่มี-sสวิทช์:

$ cut -d" " -f1-6 sample.txt 
This is a space string.
This is a space  
Thisstringcontainsneither.

$ cut -d" " -f1-6 -s sample.txt 
This is a space string.
This is a space  

ในตัวอย่างที่ 2 คุณจะเห็นว่า-sสวิทช์ได้ละเว้นสตริงใด ๆ Spaceจากการส่งออกที่ไม่ได้มีตัวคั่น,


8

เขตข้อมูลตาม POSIX เป็นส่วนหนึ่งของบรรทัดใด ๆ ที่คั่นด้วยอักขระใด ๆ ในIFS" ตัวคั่นเขตข้อมูลอินพุต (หรือตัวคั่นเขตข้อมูลภายใน ) " ค่าเริ่มต้นของพื้นที่นี้คือพื้นที่ตามด้วยตัวสร้างแนวนอนตามด้วย newline . ด้วย Bash คุณสามารถเรียกใช้printf '%q\n' "$IFS"เพื่อดูค่าของมัน


ทำเพื่อดูว่าค่าเริ่มต้นมีลักษณะเช่นเดียวกับในecho '$IFS' | cat -vet shell
C0deDaedalus

1
IFS ถูกใช้โดยเชลล์เพื่อจุดประสงค์ส่วนใหญ่ (ไม่ใช่ทั้งหมด) แต่ไม่ใช่โดยโปรแกรมอื่นและโดยเฉพาะอย่างยิ่งไม่ใช่cutซึ่งเป็นคำถามที่ถาม
dave_thompson_085

ซึ่งแตกต่างจาก awk การตัดยังสนับสนุนตัวคั่นเพียงหนึ่งตัวต่อครั้งดังนั้นcut -d "$IFS"จะเกิดข้อผิดพลาดในขณะที่awk -F"[ \t\n]"ทำงานตามที่คาดไว้
JGurtz

2

มันขึ้นอยู่กับยูทิลิตี้ที่เป็นปัญหา แต่สำหรับcut"ฟิลด์" เริ่มต้นที่จุดเริ่มต้นของบรรทัดข้อความและรวมทุกอย่างจนถึงแท็บแรก เขตข้อมูลที่สองเรียกใช้จากอักขระหลังจากแท็บแรกจนถึงแท็บถัดไป และสำหรับลำดับที่สามสี่ ... ทุกอย่างระหว่างแท็บหรือระหว่างจุดเริ่มต้นและแท็บหรือระหว่างแท็บและจุดสิ้นสุดของบรรทัด

ยกเว้นว่าคุณระบุตัวคั่นฟิลด์ด้วยตัวเลือก "-d": cut -d: -f2คุณจะได้รับทุกอย่างระหว่างอักขระโคลอนแรกและโคลอนที่สอง (':')

โปรแกรมอรรถประโยชน์อื่น ๆ มีคำจำกัดความที่แตกต่างกัน แต่แท็บอักขระทั่วไป awkเป็นการถอยกลับที่ดีหากcutเข้มงวดเกินไปเนื่องจากawkแบ่งเขตข้อมูลตามอักขระช่องว่างอย่างน้อยหนึ่งตัว นั่นเป็นเรื่องที่ค่อนข้างเป็นธรรมชาติมากขึ้นในหลาย ๆ สถานการณ์ แต่คุณต้องรู้จักไวยากรณ์บ้างเล็กน้อย หากต้องการพิมพ์ฟิลด์ที่สองตามawk :

awk '{print $2}'

sortเป็นคนที่หลอกฉัน sortหน้าคนปัจจุบันของฉันพูดบางอย่างเช่น "การไม่เปลี่ยนเป็นว่างเปล่า" สำหรับตัวคั่นฟิลด์ ด้วยเหตุผลบางอย่างการพยายามsortกำหนดเขตข้อมูลอย่างถูกต้องใช้เวลาสักครู่joinเห็นได้ชัดว่าใช้เขตข้อมูล "คั่นด้วยช่องว่าง" ซึ่งเป็นสิ่งที่awkอ้างว่าทำตามค่าเริ่มต้น

คุณธรรมของเรื่องคือต้องระวังและทดลองถ้าคุณไม่รู้


2

คำว่า "field" ไม่เกี่ยวข้องกับ linux โดยทั่วไป แต่สำหรับโปรแกรมเฉพาะ ดังนั้นcutใช้สนามที่แตกต่างกว่าsortใช้ชนิดที่แตกต่างของสนามกว่า

กับ cutคุณกำหนดว่าฟิลด์ใดเป็นตัวคุณเองโดยระบุตัวคั่นฟิลด์ด้วยตัวเลือก -d ซึ่งแยกฟิลด์ในแต่ละบรรทัด

หากข้อมูลของคุณถูกคั่นด้วยเครื่องหมายทวิภาคในบรรทัดคุณสามารถรวม-dและ-fรับฟิลด์ (หรือคอลัมน์) 2, 3 และ 6 ดังนี้:

echo 'a:b:c::d:e:f' | cut -d : -f 2-3,6

1

เมื่อคุณใช้cutคำสั่งมันจะใช้เวลาสองข้อโต้แย้งหลัก

-d: ซึ่งย่อมาจากตัวคั่น

-f: ซึ่งย่อมาจากฟิลด์ที่จะถูกตัดออกจากไฟล์อินพุต

Ex. cut - d "|"  - f1, 2 input_filename

ที่นี่outputจะคั่นด้วยตัวคั่น "|" และมันจะตัดเพียง 2 ฟิลด์จากไฟล์อินพุต

หากคุณมีบรรทัดต่อไปนี้ในไฟล์ของคุณ

Alex|120000|Admin|1999

จากนั้นมันจะตัด 2 ฟิลด์ซึ่ง ได้แก่

Alex|120000

ตัวอย่างของคุณแตกอย่างสมบูรณ์เนื่องจากช่องว่างไม่ถูกต้องและแม้ว่าจะถูกต้องสิ่งนี้จะไม่เพิ่มคำตอบใด ๆ เมื่อ 4 ปีก่อน
dave_thompson_085

0

cutดีมากสำหรับกรณีง่าย ๆ ที่ตัวคั่นเป็นอักขระเดียวและคุณต้องการส่งออกชุดย่อยของฟิลด์อินพุตในลำดับเดียวกัน (แม้ว่าฉันจะระบุ-f3,2,1มันก็ทำหน้าที่เหมือน-f1,2,3)

awkหนึ่งเส้นขอบมีความยืดหยุ่นมากขึ้นเช่นเมื่อตัวคั่นเขตข้อมูลอินพุตอาจเป็นช่องว่างใด ๆ ( awkค่าเริ่มต้น) หรือเมื่อคุณต้องการที่จะเอาท์พุทเขตข้อมูลในลำดับที่แตกต่างกันหรือในรูปแบบเฉพาะ

ยกตัวอย่างเช่นwc -l myfile | awk '{print $1}'หรือls -l file1 file2 | awk '{printf "%s,%s:%s\n", $9, $7, $3}'มีความเรียบง่ายมาก cutแต่จะยากที่จะทำอย่างไรกับ

ฉันเห็นด้วยกับผู้โพสต์ก่อนหน้านี้ว่าฟิลด์ / คีย์sortนั้นยากที่จะคิดออก! เขตข้อมูลในjoinดูเหมือนจะทำงานเหมือนกับในcutแม้ว่าjoinตัวเลือกจะผิดได้ง่าย

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