特定の文字列までの行の一部を抽出する

特定の文字列までの行の一部を抽出する

次のような行を含むファイルがあるとします。

/java/jdkxx/jvm_jdk/bin/opt
/java/jre/jre_jvm/bin/opt
/foo/bar/bin/other/stuff/here

までの行の一部を抽出する方法はありますかbin。つまり、それらの行がfile.txt次の位置にあると仮定します。

$ <some_command> file.txt 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/
/foo/bar/bin/

答え1

これを行うには多くの方法があります。以下にいくつか例を挙げます。

# greedily caputure up to the last slash
grep -o '.*/bin/' file.txt
# remove all non-slash chars from the end of each line
sed 's#\(/bin/\).*$#\1#' file.txt
# using slash as a delimiter, blank out the last field
awk -F/ -v OFS=/ '{for (i=1; i<=NF; i++) if ($i == "bin") {NF=i; break}} 1' file.txt

答え2

純粋な bash の方法:

while read -n line
do
    [[ $line =~ /bin/ ]] && printf "%s\n" "${line/%\/bin\/*//bin/}"
done

答え3

え、Perl がないの?

perl -ne 's#/bin\K.*## && print' file

もしあなたがそれを知っていたら全て行に必要なパターンが含まれている場合は、次のように簡略化できます。

perl -pe 's#/bin\K.*##' file

は、「」\Kの前のすべてを無視することを意味する PCRE 式です\K


次のようなこともできます

awk -F"/bin" '{print $1FS}' file

これにより、awk のフィールド区切り文字 ( FS) が に設定され/bin、最初のフィールドと の値FS( /bin) が出力されます。この場合も、すべての行が必要であると想定されます。そうでない場合は、代わりに次のコードを使用します。

awk -F"/bin" '($2){print $1FS}' file

答え4

他の良い回答とともに、 の後に続くものはすべて/bin/印刷されないようにする次の方法を試すこともできます。

grep -Po ".*/(?<=/bin/)" file

例:

$ cat test_file 
/java/jdkxx/jvm_jdk/bin/opt
/java/jre/jre_jvm/bin/opt/home

$ grep -Po ".*/(?<=/bin/)" test_file 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/

ここでは、ペクレ肯定的な後読みを使用(?<=/bin/)して、 までしか取得しないことを確実にします。最終的に/が得られます。/bin/

関連情報