bashを使用してパス文字列の1つの要素を取得する


9

次のコマンドを実行して読み取るファイルパスを含むASCIIファイルがあります。

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

ファイルには、次のパターンのファイルパスが含まれています。

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

パス文字列の特定の部分(from /から/)を取得するにはどうすればよいですか。たとえば、次のような出力を取得する必要があります。

first
second
third

そしてまた

example1
example1
example2

正規表現とを使用してこれを行う方法は確かにありますが、sed私はそれに慣れていません。

回答:


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
モンティハーダー

1
また、whileを回避すると、引用の問題が回避され、ファイル名の改行で失敗しなくなります。
Volker Siegel

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

2番目の/区切りフィールドと

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

3番目の/区切りフィールド。

  • -l:自動改行処理を有効にします。2つの異なる効果があります。まず、-nまたは-pと一緒に使用すると、$ /(入力レコード区切り文字)が自動的に表示されます。次に、$ \(出力レコードセパレーター)をoctnumの値に割り当てて、すべての印刷ステートメントにそのセパレーターが追加されるようにします。octnumを省略すると、$ \を$ /の現在の値に設定します。
  • -a:-nまたは-pとともに使用すると、自動分割モードがオンになります。@F配列への暗黙の分割コマンドは、-nまたは-pによって生成される暗黙のwhileループ内で最初に実行されます。
  • -n:プログラムの周りでPerlが次のループを想定するようにします。これにより、sed -nまたはawkのようなファイル名引数を反復処理します。

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e:プログラムの1行を入力するために使用できます。

  • 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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.