/path/to/file 分割

/path/to/file 分割

ファイルへの明示的なパスがあります。

/aaa/bbb/ccc/ddd/eee/fff.txt

cd /aaa/bbbの作業を行う必要がありますccc/ddd/eee/fff.txt

私は最初のポイントを理解しています。

df_test=/aaa/bbb/ccc/ddd/eee/fff.txt
cd $( echo ${df_test} | awk -F/ '{print "/"$2"/"$3}' )

それでは、パスの最初の2つのステップを切り取り、残りはどのように作業しますか?また、これらのファイルがどれほど深いかを事前に知ることはできません。私が持つことができます

/aaa/bbb/ccc/ddd.txt
/aaa/bbb/ccc/ddd/eee/fff.txt
/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt

私はディレクトリを/ aaa / bbbに変更し、残りの相対パスで作業する必要がありました。

答え1

標準シェルから:

$ path=/aaa/bbb/ccc/ddd/eee/fff.txt
$ tail="${path#/*/*/}"
$ head="${path%/$tail}"
$ echo "$head" "$tail"
/aaa/bbb ccc/ddd/eee/fff.txt

"${path#/*/*/}"path/*/*/はい。ただし、(最も短い)先行部分、つまり末尾部分と一致する値を削除します。その後、スラッシュを"${path%/$tail}"使用して尾を削除します。path

パスに十分なコンポーネントがないと、破損した結果が発生するため、最初に確認することをお勧めします。

または、Bashでは正規表現の一致を使用して[[ .. ]]一致するフラグメントを選択できます。

$ if [[ $path =~ (/[^/]+/[^/]+)/(.*) ]]; then 
    echo "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
fi 
/aaa/bbb ccc/ddd/eee/fff.txt

[[ ... ]]ifしたがって、条件に応じてパスに十分なコンポーネントがあることを確認するためにここで使用するのは簡単です。

答え2

私は個人的にcutこれが好きです:

$ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | cut -d'/' -f4-
ccc/ddd/eee/fff.txt

-f解決したいディレクトリツリーの深さに合わせてパラメータを調整するだけです。

以下を使用して、最初の2つのフィールドを削除する方法を示しますawk

$ echo "/aaa/bbb/ccc/ddd/eee/fff.txt" | awk -F'/' -v OFS='/' '{$1=$2=$3=""; print}' | sed 's#///##'
ccc/ddd/eee/fff.txt

答え3

プレフィックスは静的であるため、パラメータ拡張を使用して削除できます。

df_test=/aaa/bbb/ccc/ddd/eee/fff/ggg/hhh/iii.txt
cd /aaa/bbb
operate=${df_test#/aaa/bbb}
echo Operating on "$operate"

関連情報