Lấy một phần của một dòng trước dấu gạch chéo cuối cùng


7

Tôi đang cố gắng viết một kịch bản conky thể hiện nghệ thuật album MPD của tôi, một 'thư mục.jpg' trong thư mục album. Kế hoạch hiện tại của tôi là sử dụng mpc -f %file%, in ra tên và đường dẫn của tệp, sau đó cắt tên tệp thực tế (tức là mọi thứ sau lần cuối /) và sử dụng đó làm đường dẫn cho đối tượng hình ảnh của conky.

Tôi gặp sự cố với grep / cut, đặc biệt vì một số bài hát được lồng trong hai thư mục, trong khi những bài khác nằm trong một. ( grep -m 1 . |cut -f1 -d /hoạt động cho các album thư mục đơn)

Làm thế nào tôi sẽ đi về điều này? Có cách nào đơn giản hơn tôi đang thiếu?


Bạn có muốn phần thư mục lên đến cuối cùng /, hoặc tên tệp mà không có phần thư mục hàng đầu? Cắt ra ra là mơ hồ, và chúng tôi đã giải thích nó khác nhau.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Từ ví dụ của anh ấy với các album thư mục đơn, OP muốn giữ lại phần trước dấu gạch chéo cuối cùng.
vinc17

Câu trả lời:


9

Bạn có thể sử dụng sedđể xóa phần còn lại - mọi thứ bắt đầu bằng dấu gạch chéo cuối cùng :

mpc -f %file% | head -1 | sed 's:/[^/]*$::'

Mẫu /[^/]*$phù hợp với một dấu gạch chéo, theo sau là bất kỳ ký tự nào ngoại trừ dấu gạch chéo, cho đến cuối dòng. Nó được thay thế bằng chuỗi rỗng.
Việc head -1bỏ qua một số đầu ra trạng thái theo dòng chúng tôi muốn - nhưng xem bên dưới để biết cách không pring chúng ở vị trí đầu tiên.

Trong trường hợp bạn không quen sử dụng sed, lệnh có thể trông bất thường vì :được sử dụng. Bạn có thể đã thấy sedcác lệnh với /dấu phân cách trước đây, như 's/foo/bar/'- Tôi thích sử dụng dấu phân cách :để dễ đọc, vì biểu thức chứa /chính nó. Ngoài ra, chúng ta có thể thoát khỏi /biểu thức: 's/\/[^\/]*$//'- điều đó không làm cho nó dễ đọc hơn.


Cách bạn sử dụng nó mpccung cấp cho bạn hai dòng trạng thái bổ sung. Tùy chọn -qcho yên lặng tắt tất cả đầu ra. Bạn cần kết hợp -qvới in rõ ràng tệp đang phát để có được dòng yon cần, và không có gì nữa:

mpc -q -f %file% current | sed 's:/[^/]*$::'

Thay vì xóa mọi thứ bắt đầu bằng dấu gạch chéo cuối cùng , người ta có thể in rõ ràng mọi thứ trước dấu gạch chéo cuối :

mpc -q -f %file% current | sed 's:^\(.*\)/.*$:\1:'

Điều đó phù hợp với bất kỳ nhân vật nào được theo sau bởi một /và bất kỳ nhân vật nào khác; Nó khớp càng nhiều càng tốt, sao cho /cái được khớp sẽ là cái cuối cùng.


Cảm ơn rất nhiều. Cờ -q cũng giúp rất nhiều.
rargh

3

Nếu bạn muốn áp dụng quy tắc này trên một chuỗi, sau đó thay vì sed(xem câu trả lời khác), bạn có thể sử dụng dirnamelệnh:

$ dirname "1 2/3 4/5 6/file"
1 2/3 4/5 6

2

Grep không phải là công cụ cuối cùng cho công việc. grep -m 1 .in dòng không trống đầu tiên, không hữu ích. Bạn có thể xây dựng các giải pháp phức tạp liên quan đến grep và các công cụ khác, nhưng cách đơn giản là với sed . Một cách là thay thế một ký tự không gạch chéo cuối cùng, cộng với dấu gạch chéo trước, bằng chuỗi trống:

mpc -f %file% | sed 's:/[^/]*$::'

Ngoài ra, giữ mọi thứ cho đến dấu gạch chéo cuối cùng và loại bỏ những gì sau đây:

mpc -f %file% | sed 's:^\(.*\)\(/.*\)$:\1:'

Lưu ý rằng cả hai phương thức đều giữ nguyên đầu vào nếu nó không chứa a /, tức là nếu bạn truyền tên tệp không có chỉ dẫn thư mục. Mặc dù bạn có thể giải quyết vấn đề này trong sed nếu đó là một vấn đề, việc gọi dirnamelệnh dễ dàng hơn :

dirname -- "$(mpc -f %file%)"

Trong tập lệnh shell, bạn cũng có thể sử dụng các cấu trúc mở rộng tham số , nhưng điều này phức tạp hơn nếu bạn chỉ muốn in ra kết quả:

full_path="$(mpc -f %file%)"
case "$full_path" in
  */*) directory_part="${full_path%/*}"
  *) directory_part="."
printf '%s\n' "$directory_part"
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.