使用bash获取路径字符串的一个元素


9

我有一个包含通过运行读取的文件路径的ASCII文件:

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

该文件包含具有以下模式的文件路径:

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

如何获取路径字符串的特定部分(从//),例如,我需要获取打印的输出:

first
second
third

并且

example1
example1
example2

我敢肯定有一种使用正则表达式和进行此操作的方法sed,但是我对此并不熟悉。

Answers:


17

用途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

-d/设置列分隔符/-f2选择第2列。

当然,您也可以使用Bash变量而不是文件名或将数据传送到cut命令中:

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

| cut -d/ -f3 在管道中使用可以达到目的。谢谢!现在这是完整的命令: while read p; do echo $p; done < filelist.txt | cut -d/ -f3
mcExchange

3
@mcExchange没有理由使用while循环。要做起来要简单得多 cut -d/ -f3 filelist.txt
Monty Harder

1
另外,避免使用while可以避免引用问题,并且不会因文件名中的换行而失败。
Volker Siegel'Mar

10

您可以直接在read命令中使用IFS变量,例如

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

5

您可以使用 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

如果我们想要路径的任何元素,则最好使用可以将字符串分解为字段的内容,例如 , 要么 。然而, 也可以使用参数替换,使用模式替换并将所有内容都放入数组来完成这项工作。

$> 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

现在,我们有一系列由路径组成的项目。请注意,如果路径包含空格,则可能涉及更改内部字段分隔符IFS


1

Bash和cut是可行的方法,但是使用Perl的替代方法是:

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

第二个定/界字段和

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

用于第三个定/界字段。

  • -l:启用自动行结束处理。它有两个单独的作用。首先,当与-n或-p一起使用时,它会自动砍掉$ /(输入记录分隔符)。其次,它将$ \(输出记录分隔符)分配为octnum的值,以便任何打印语句将重新添加该分隔符。如果省略octnum,则将$ \设置为$ /的当前值。
  • -a:当与-n或-p一起使用时,将打开自动分割模式。对@F数组的隐式split命令是由-n或-p生成的隐式while循环内的第一件事。
  • -n:使Perl在您的程序周围假设以下循环,从而使其遍历文件名参数,如sed -n或awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e:可用于进入程序的一行;

  • print(@F[N]):打印第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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.