ทำไมคำสั่ง pipe“ l | grep” 1“” ได้รับผลที่ผิดหรือเปล่า?


13

ดังที่แสดงในรูปภาพฉันใช้lเพื่อรับไฟล์ในโฟลเดอร์ปัจจุบัน แล้วฉันต้องการที่จะได้รับไฟล์ที่มีจำนวน1ดังนั้นฉันใช้และpipegrep

แต่ทำไม2และ22ไฟล์จึงแสดงออกมา และอะไรคือสิ่งที่1;34m?

$ l
./ ../ 1 11 2 22
$ l | grep "1"
1;34m./ 1;32m../ 1 11 2 22

ปรับปรุง

ฉันได้ตั้งชื่อแทนคำสั่งlไว้ในzshrcไฟล์แล้ว

 alias lsp="ls"
 alias ll='ls -alF'
 alias la='ls -A'
 alias l='ls -CF'
 alias ls="ls -alh --color"

และนี่คือผลลัพธ์ของtypeคำสั่ง:

>$ type ls
ls is an alias for ls -alh --color

> $ type l
l is an alias for ls -CF

4
โปรดอย่าโพสต์ภาพหน้าจอของข้อความ คัดลอกข้อความที่นี่และใช้การจัดรูปแบบรหัส
muru

@muru ฉันคิดว่าคุณหมายถึงการขอออกโพสต์ของtype -a l?
WinEunuuchs2Unix

@ WinEunuuchs2Unix อ่าใช่
muru

@ ฉันจะขอให้คุณโพสต์เอาท์พุทของtype lsคำสั่งได้ไหม? คุณแก้ไขlsนามแฝงในทางใดทางหนึ่งแล้วหรือยัง
Sergiy Kolodyazhnyy

@Serg อัปเดตแล้ว
ลี

คำตอบ:


27

ก่อนอื่นสิ่งที่คุณกำลังพยายามทำl| grep <filename>อยู่นั้นไม่ดี อย่าทำมัน นี่คือเหตุผล

l คำสั่งเป็นนามแฝงจริงๆ ls -CF

$ type -a l
l is aliased to `ls -CF'

โดยเริ่มต้นในของ Ubuntu bash, เป็นนามแฝงที่จะls ls --color=autoในฐานะที่เป็นผู้ขับรถเหล็กชี้ให้เห็นในความคิดเห็นที่--color=autoควรจะปิด colorization ในกรณีที่เฉพาะเจาะจงของคุณคุณมีalias ls="ls -alh --color"และซึ่งโดยทั่วไปสิ้นสุดขึ้นเป็นalias l="ls -CF" ls -alh --color -CFการรวมกันโดยเฉพาะอย่างยิ่งของสวิทช์ยังคงส่งออก colorized ผ่านท่อ ตัวอย่างเช่น:

$ ls -alh --color -CF ~/TESTDIR | cat -A                                                                                 
^[[0m^[[01;34m.^[[0m/  ^[[01;34m..^[[0m/  1.txt  2.txt  3.txt  out.txt$

ขอให้สังเกตว่า.และ..ไดเรกทอรีมีลำดับการหลีกเลี่ยงเดียวกัน

ทั้งหมดนี้หมายความว่าอย่างไร

ซึ่งหมายความว่าlจะแสดงรายการไฟล์ที่เป็นสีตามประเภทไฟล์ ปัญหาคือว่า colorization ที่เกิดขึ้นกับการใช้งานของลำดับหนี นั่นคือสิ่ง1:34mที่พวกเขากำลังหลบหนีลำดับสำหรับสีที่เฉพาะเจาะจง

ปัญหาหลักคือการแยกวิเคราะห์lsมักจะนำไปสู่ผลลัพธ์ที่ไม่ถูกต้องและภัยพิบัติในสคริปต์เนื่องจากlsอนุญาตให้ใช้ลำดับการยกเว้นเช่นอธิบายก่อนหน้านี้และอักขระพิเศษอื่น ๆ ดูบทความนี้สำหรับข้อมูลเพิ่มเติม: http://mywiki.wooledge.org/ParsingLs

สิ่งที่คุณควรทำ:

ใช้findคำสั่ง:

bash-4.3$ ls
1.txt  2.txt  3.txt  out.txt
bash-4.3$ find . -maxdepth 1 -iname "*1*"
./1.txt

คุณสามารถทำสิ่งนี้กับเชลล์ glob และ[[คำสั่งการทดสอบที่ทันสมัย:

bash-4.3$ for file in * ;do if [[ "$file" =~ "1"  ]] ;then echo "$file" ;fi ; done
1.txt

หรืออาจใช้ python ซึ่งมีความสามารถในการจัดการชื่อไฟล์ได้ดีกว่าbashคนเดียว

bash-4.3$ python -c 'import os;print [f for f in os.listdir(".") if "1" in f ]'
['1.txt']

หากไม่จำเป็นต้องประมวลผลเอาท์พุทการlsทำให้เป็นก้อนกลมเรียบง่ายlsก็สามารถทำงานได้เช่นกัน (โปรดจำไว้ว่านี่เป็นเพียงการดูรายการไฟล์เท่านั้นไม่ใช่เพื่อส่งไปยังโปรแกรมอื่นเพื่อจัดการกับข้อความเอาต์พุต)

bash-4.3$ ls *1*
1.txt

2
ฉันคิดว่าเอาต์พุตจะถูกทำให้เป็นสีในไพพ์หาก--color=alwaysระบุด้วย - ไม่ว่าจะเป็นส่วนหนึ่งของนามแฝงสำหรับlหรือในนามแฝงก่อนหน้าสำหรับlsตัวเอง (แทนที่ค่าเริ่มต้นalias ls='ls --color=auto')
ขับเหล็ก

@steeldriver จุดดี แต่นั่นไม่ใช่สิ่งที่lsทุบตีโดยค่าเริ่มต้นคืออะไร? type lsให้ฉันว่ามันเป็นนามแฝงสำหรับls --color=auto
Sergiy Kolodyazhnyy

1
ใช่นั่นเป็นค่าเริ่มต้น - แต่autoจะปิดสีในไพพ์ AFAIK หากต้องการดูลำดับสี ANSI จะต้องมีการเปลี่ยน--color=alwaysเป็นในlsนามแฝงหรือlนามแฝง
steeldriver

โอ้ฉันเห็นสิ่งที่คุณหมายถึง มันแปลกมาก
Sergiy Kolodyazhnyy

@steeldriver ดังนั้นฉันขอให้ OP โพสต์นามแฝงของเขาและเห็นได้ชัดว่าสิ่งที่พวกเขามีคือls --colorไม่ได้ป้องกันการเปลี่ยนสี (ทดสอบด้วยตัวเองเช่นกัน) อัปเดตคำตอบของฉันตามนั้น
Sergiy Kolodyazhnyy

6

คำสั่งของคุณlและlsถูกตั้งค่าเป็นนามแฝง

เมื่อคุณเรียกใช้พวกเขาไปป์พุทผ่านgrep "1"(โดยใช้|) แต่ละบรรทัดหน้าจอที่1ปรากฏจะปรากฏขึ้นพร้อมกับ1สีแดง

เพราะชื่อไฟล์., .., 2และ22ปรากฏบนบรรทัดหน้าจอเดียวกันพวกเขาจะออกโดยgrepเช่นกัน แต่ไม่ปรากฏในสีแดงซึ่งแสดงให้เห็นว่าgrepการแข่งขัน

:34mเป็นลำดับหนีสำหรับสีที่ไม่ได้ทาสีอย่างถูกต้อง ตามคำถามที่แก้ไขของคุณด้วยผลลัพธ์type -a lและtype -aสามารถทำซ้ำได้ในระบบของฉัน โปรดทราบว่าคุณควรเปลี่ยนนามแฝงของคุณ--colorเป็น--color=auto:

เอาท์พุทสี

สี ls


1:34mสิ่งที่ไม่ทุจริตพวกเขากำลังลำดับหนีใช้สำหรับ colorization ของข้อความ ดูคำตอบของฉันในส่วนนั้น)
Sergiy Kolodyazhnyy

@Serg ขอบคุณ ฉันได้แก้ไขตามคำถามที่แก้ไข OP ด้วยนามแฝง
WinEunuuchs2Unix

1

ในการทดลองของคุณคุณกำลังเรียกlsนามแฝงของคุณดังนั้น1;34mเสียงที่คล้ายกันซึ่งมาจากการระบายสีและเนื่องจากไพพ์|ได้รับทั้งหมดนี้ในบรรทัดเดียวกันการgrepจับคู่ไฟล์1จากบรรทัดนั้นจึงพิมพ์บรรทัดนี้ นี่คือสิ่งที่คุณเห็นบนหน้าจอ

เมื่อคุณทำสิ่งต่าง ๆ เช่นนั้นมันเป็นการดีเสมอที่จะกลับไปที่คำสั่งระบบด้วย 1 ผลลัพธ์ต่อบรรทัด

หากต้องการกำจัดนามแฝงให้พิมพ์\lsและใช้ตัวเลือก-1เพื่อพิมพ์ผลลัพธ์ที่คั่นด้วยตัวดึงข้อมูลบรรทัด

$ \ls -1 | grep "1"
1
11

หมายเหตุ: เมธอดแบ็กสแลชทำงานกับทุกคำสั่ง\commandเพียงเรียกใช้คำสั่งระบบที่ไม่รวม

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