Nhận một phần tử của chuỗi đường dẫn bằng cách sử dụng bash


9

Tôi có một tệp ASCII chứa filepath mà tôi đọc bằng cách chạy:

while read p; do echo $p; done < filelist.txt

Tệp này chứa các filepath với mẫu sau:

./first/example1/path
./second/example1/path
./third/example2/path

Làm cách nào tôi có thể nhận được một phần cụ thể của chuỗi đường dẫn (từ /đến /), ví dụ: tôi cần có một đầu ra in:

first
second
third

và cũng

example1
example1
example2

Tôi chắc chắn có một cách để làm điều này bằng cách sử dụng các biểu thức thông thường và sed, nhưng tôi không quen với nó.

Câu trả lời:


17

Sử dụng cut:

$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path

$ cut -d/ -f2 filelist.txt 
first
second
third

$ cut -d/ -f3 filelist.txt 
example1
example1
example2

Bộ -d/đặt dấu phân cách cột thành /-f2chọn cột thứ 2.

Tất nhiên bạn cũng có thể sử dụng các biến Bash thay vì tên tệp hoặc dữ liệu đường ống vào cutlệnh:

cut -d/ -f3 $MyVariable
echo ./another/example/path | cut -d/ -f3

Sử dụng | cut -d/ -f3 trong một đường ống đã lừa Cảm ơn! Đây là lệnh đầy đủ ngay bây giờ: while read p; do echo $p; done < filelist.txt | cut -d/ -f3
mcExchange

3
@mcExchange Không có lý do để sử dụng vòng lặp while đó. Thật đơn giản để làm cut -d/ -f3 filelist.txt
Monty Harder

1
Ngoài ra, tránh trong khi tránh trích dẫn các vấn đề và sẽ không thất bại với dòng mới trong tên tệp.
Volker Siegel

10

Bạn có thể làm điều đó trực tiếp trong readlệnh của mình , sử dụng IFSbiến, ví dụ

$ while IFS=/ read -r p1 p2 p3 r; do echo "$p2"; done < filelist.txt 
first
second
third

5

Bạn có thể dùng awk

pilot6@Pilot6:~$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path

pilot6@Pilot6:~$ awk -F "/" '{print $2}' filelist.txt
first
second
third

pilot6@Pilot6:~$ awk -F "/" '{print $3}' filelist.txt
example1
example1
example2

3

Nếu chúng ta muốn bất kỳ phần tử nào của đường dẫn, tốt nhất là sử dụng thứ gì đó có thể chia chuỗi thành các trường, chẳng hạn như , , hoặc . Tuy nhiên, cũng có thể thực hiện công việc với sự thay thế tham số, sử dụng thay thế mẫu và ném mọi thứ vào một mảng.

$> echo ${FILE//\//\ }                                                         
sys class backlight intel_backlight brightness
$> ARRAY=( ${FILE//\//" " } )                                                  
$> echo ${ARRAY[2]}
backlight

$> FILE="./dir1/dir2/file.txt"                                                 
$> ARRAY=( ${FILE//\/" "} )
$> echo ${ARRAY[@]}                                                            
. dir1 dir2 file.txt
$> echo ${ARRAY[1]}
dir1

Bây giờ chúng ta có một loạt các mục được tạo ra từ đường dẫn. Lưu ý rằng nếu đường dẫn chứa khoảng trắng, nó có thể liên quan đến việc thay đổi dấu tách trường bên trong IFS.


1

Bash và cutlà cách để đi, tuy nhiên một cách khác là sử dụng Perl:

perl -F/ -lane 'print(@F[1])' filelist.txt

cho trường giới hạn thứ hai /

perl -F/ -lane 'print(@F[2])' filelist.txt

cho trường giới hạn thứ ba /.

  • -l: cho phép xử lý kết thúc dòng tự động. Nó có hai hiệu ứng riêng biệt. Đầu tiên, nó tự động nhai $ / (dấu tách bản ghi đầu vào) khi được sử dụng với -n hoặc -p. Thứ hai, nó gán $ \ (dấu tách bản ghi đầu ra) có giá trị octnum để bất kỳ câu lệnh in nào sẽ có dấu phân cách đó được thêm lại. Nếu octnum bị bỏ qua, đặt $ \ thành giá trị hiện tại là $ /.
  • -a: bật chế độ tự động nhận khi được sử dụng với -n hoặc -p. Lệnh chia ngầm định cho mảng @F được thực hiện như là điều đầu tiên bên trong vòng lặp ngầm định được tạo bởi -n hoặc -p.
  • -n: khiến Perl giả định vòng lặp sau xung quanh chương trình của bạn, điều này làm cho nó lặp đi lặp lại qua các đối số tên tệp có phần giống như sed -n hoặc awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: có thể được sử dụng để nhập một dòng chương trình;

  • print(@F[N]): in trường thứ N.
% cat filelist.txt 
./first/example1/path
./second/example1/path
./third/example2/path
% perl -F/ -lane 'print(@F[1])' filelist.txt
first
second
third
% perl -F/ -lane 'print(@F[2])' filelist.txt
example1
example1
example2
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.