Tại sao lệnh đường ống L | grep xông 1 tôn phạm có được kết quả sai?


13

Như hình ảnh minh họa, tôi sử dụng lđể lấy tệp trong thư mục hiện tại. Và sau đó tôi muốn lấy tệp có số 1, vì vậy tôi sử dụng pipegrep.

Nhưng tại sao 222tập tin hiển thị? Và là 1;34mgì?

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

Cập nhật

Tôi đã bí danh lệnh ltrong zshrctập tin của tôi .

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

Và đây là kết quả của typelệnh:

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

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

4
Xin vui lòng không đăng ảnh chụp màn hình của văn bản. Sao chép văn bản ở đây và áp dụng định dạng mã.
muru

@muru Tôi nghĩ bạn muốn hỏi đầu ra của type -a l?
WinEunuuchs2Unix

@ WinEunuuchs2Unix ah, vâng.
muru

@Lee tôi có thể yêu cầu bạn gửi đầu ra của type lslệnh xin vui lòng? Bạn đã sửa đổi lsbí danh theo cách nào?
Sergiy Kolodyazhnyy

@Serg đã được cập nhật.
Lee

Câu trả lời:


27

Trước hết, những gì bạn đang cố gắng làm, l| grep <filename>là xấu. Đừng làm điều đó. Đây là lý do tại sao.

l lệnh thực sự là một bí danh để ls -CF

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

Theo mặc định trong Ubuntu bash, lslà một bí danh ls --color=auto. Như Steeldo đã chỉ ra trong các ý kiến --color=autođược cho là tắt màu. Trong trường hợp cụ thể của bạn, bạn có alias ls="ls -alh --color"alias l="ls -CF", về cơ bản kết thúc là ls -alh --color -CF. Sự kết hợp đặc biệt này của các công tắc vẫn gửi đầu ra được tô màu qua một đường ống. Ví dụ:

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

Lưu ý cách .và các ..thư mục có trình tự thoát giống nhau.

Tất cả điều này có nghĩa là gì

Điều này có nghĩa là lsẽ xuất ra danh sách các tệp màu theo loại tệp. Vấn đề là sự tô màu xảy ra với việc sử dụng các chuỗi thoát . Đó là những gì 1:34mđang có - chúng là chuỗi thoát cho các màu cụ thể.

Vấn đề chính là phân tích cú pháp lsthường dẫn đến đầu ra sai và thảm họa trong các tập lệnh, đơn giản là vì lscho phép các chuỗi thoát như được giải thích trước đó và các ký tự đặc biệt khác. Xem bài viết này để biết thêm: http://mywiki.wooledge.org/ParsingLs

Những gì bạn nên làm:

Sử dụng findlệnh:

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

Bạn có thể làm một cái gì đó như thế này với [[lệnh thử toàn cầu và hiện đại shell :

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

Hoặc có thể sử dụng python, có khả năng xử lý tên tệp tốt hơn nhiều so với bashmột mình

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

Nếu không cần xử lý đầu ra ls, quá trình tạo khối đơn giản lscũng có thể thực hiện công việc. (Hãy nhớ rằng, đây chỉ để xem danh sách các tệp, không phải để chuyển nó sang chương trình khác để xử lý văn bản đầu ra)

bash-4.3$ ls *1*
1.txt

2
Tôi nghĩ rằng đầu ra sẽ chỉ được tô màu trong một đường ống nếu --color=alwayscũng được chỉ định - là một phần của bí danh cho lhoặc trong một bí danh trước đó cho lschính nó (thay thế mặc định alias ls='ls --color=auto').
Steeldo

@steel ấn Điểm tốt, nhưng đó không phải là những gì lstrong bash theo mặc định là? type lscho tôi biết đó là bí danh chols --color=auto
Sergiy Kolodyazhnyy

1
Có, đó là mặc định - nhưng autotắt màu trong ống AFAIK. Để được nhìn thấy các chuỗi màu ANSI, nó phải được đổi thành --color=always, trong lsbí danh hoặc lbí danh
Steeldo

Ồ, tôi hiểu ý của bạn. Điều đó thật kỳ quặc.
Sergiy Kolodyazhnyy

@steel ấn Vì vậy, tôi đã yêu cầu OP đăng bí danh của mình, và rõ ràng những gì họ có, cụ thể là ls --color, không ngăn chặn màu sắc (bản thân tôi cũng đã thử nghiệm). Cập nhật câu trả lời của tôi cho phù hợp
Sergiy Kolodyazhnyy

6

Lệnh llslệnh của bạn được thiết lập dưới dạng bí danh.

Khi bạn chạy chúng, đường ống đầu ra thông qua grep "1"(sử dụng |) từng dòng màn hình 1xuất hiện được hiển thị, với 1màu đỏ.

Bởi vì tên file ., .., 222xuất hiện trên các dòng cùng một màn hình, họ có đầu ra bởi grepcũng nhưng không xuất hiện trong màu đỏ mà chương trình greptrận đấu.

Đây :34mlà một chuỗi thoát cho một màu không vẽ đúng. Dựa trên câu hỏi sửa đổi của bạn với đầu ra type -a ltype -anó có thể được sao chép trong hệ thống của tôi. Xin lưu ý bạn nên thay đổi bí danh của mình từ --colorthành --color=auto:

Đầu ra màu

màu ls


Những 1:34mthứ không tham nhũng, chúng là các chuỗi thoát được sử dụng để tô màu văn bản. Xem câu trả lời của tôi về phần đó;)
Sergiy Kolodyazhnyy

@Serg Cảm ơn bạn. Tôi đã sửa đổi dựa trên câu hỏi sửa đổi của OP với bí danh.
WinEunuuchs2Unix

1

Trong thử nghiệm của bạn, bạn đã gọi lsbí danh của mình , do đó, 1;34mvà tiếng ồn tương tự xuất phát từ việc tô màu, và vì đường ống |nhận được tất cả điều này trên cùng một dòng, nên grepkhớp với tệp 1từ dòng đó và do đó in dòng này. Đây là những gì bạn nhìn thấy trên màn hình.

Khi bạn đang làm những thứ như vậy, sẽ luôn tốt khi quay lại lệnh hệ thống với 1 kết quả trên mỗi dòng.

Để loại bỏ bí danh, chỉ cần gõ \lsvà sử dụng tùy chọn -1để in kết quả được phân tách bằng nguồn cấp dữ liệu.

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

Lưu ý: phương thức dấu gạch chéo ngược hoạt động với mọi lệnh, \commandchỉ cần gọi lệnh hệ thống không thiên vị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.